interface IERC223 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address account) external view returns (uint); function transfer(address to, uint value) external returns (bool); function transfer(address to, uint value, bytes memory data) external returns (bool); function transfer(address to, uint value, bytes memory data, string memory customFallback) external returns (bool); event Transfer(address indexed from, address indexed to, uint value, bytes data); }
contract ERC223 is IERC223 { string public override name; string public override symbol; uint8 public override decimals; uint public override totalSupply; mapping (address => uint) private _balances; string private constant _tokenFallback = "tokenFallback(address,uint256,bytes)";
constructor (string memory _name, string memory _symbol) public { name = _name; symbol = _symbol; decimals = 18; }
function balanceOf(address account) public view override returns (uint) { return _balances[account]; }
function transfer(address to, uint value) public override returns (bool) { return _transfer(msg.sender, to, value, "", _tokenFallback); }
function transfer(address to, uint value, bytes memory data) public override returns (bool) { return _transfer(msg.sender, to, value, data, _tokenFallback); }
function transfer(address to, uint value, bytes memory data, string memory customFallback) public override returns (bool) { return _transfer(msg.sender, to, value, data, customFallback); }
/* Helper functions */ function _transfer(address from, address to, uint value, bytes memory data, string memory customFallback) internal returns (bool) { require(from != address(0), "ERC223: transfer from the zero address"); require(to != address(0), "ERC223: transfer to the zero address"); require(_balances[from] >= value, "ERC223: transfer amount exceeds balance"); _balances[from] -= value; _balances[to] += value;
function _mint(address to, uint value) internal { require(to != address(0), "ERC223: mint to the zero address"); totalSupply += value; _balances[to] += value; emit Transfer(address(0), to, value, ""); }
function getWinner() public view returns (address) { require(stage == 3, "Election: stage incorrect"); uint maxVotes = 0; address winner = address(0); for (uint i = 0; i < candidates.length; i++) { if (voteCount[candidates[i]] > maxVotes) { maxVotes = voteCount[candidates[i]]; winner = candidates[i]; } } return winner; }
function giveMeMoney() public { require(balanceOf(msg.sender) == 0, "Election: you're too greedy"); _mint(msg.sender, 1); }
function giveMeFlag() public { require(msg.sender == getWinner(), "Election: you're not the winner"); require(proposals[msg.sender].valid, "Election: no proposal from candidate"); if (_stringCompare(proposals[msg.sender].policies, "Give me the flag, please")) { sendFlag = true; emit SendFlag(msg.sender); } }
/* Helper functions */ function _setup() public auth { address Alice = address(0x9453); address Bob = address(0x9487); _setStage(0); propose(Alice, Proposal("Alice", "This is Alice", true)); propose(Bob, Proposal("Bob", "This is Bob", true)); voteCount[Alice] = uint(-0x9453); voteCount[Bob] = uint(-0x9487); _setStage(1); }
function _setStage(uint _stage) public auth { stage = _stage & 0xff; }
function _stringCompare(string memory a, string memory b) internal pure returns (bool) { return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); }
/* custom added functions */ function testdeet(address to, uint value, bytes memory data, string memory customFallback) pure public returns (bytes memory){ return abi.encodeWithSignature(customFallback, to, value, data); }
function properEncode(address candidate, Proposal memory proposal, address t1, address t2) pure public {
}
function ballotEncode(Ballot[] memory ballots) pure public returns (bytes32){ return keccak256(abi.encode(ballots)); } }
contract A { address public temp1; uint256 public temp2; function three_call(address addr) public { addr.call(bytes4(keccak256("test()"))); // 情况1 //addr.delegatecall(bytes4(keccak256("test()"))); // 情况2 //addr.callcode(bytes4(keccak256("test()"))); // 情况3 } }
contract B { address public temp1; uint256 public temp2; function test() public { temp1 = msg.sender; temp2 = 100; } function test2() public returns (uint256){ return uint(-0x9453); } }
例如如果要利用call函数调用propose函数,address地址为0x9aC4ef4fed53a395Bcb4004Cd8DffEE73CC46800,结构体中name为kkfine,policies为Give me the flag, please,valid为true,则call函数中data的内容为
slot0 msg.sender/candidate slot1 offset of Proposal 0x0000000000000000000000000000000000000000000000000000000000000040 slot2 offset of name 0x0000000000000000000000000000000000000000000000000000000000000060 slot3 offset of plicies 0x00000000000000000000000000000000000000000000000000000000000000a0