文章
问答
讲堂
百科图谱
线下集训
更多
提问
发表文章
专栏
活动
文档
工作
集市
发现
Toggle navigation
文章
问答
讲堂
线下集训
专栏
活动
工作
文档
集市
搜索
登录/注册
5
夹子合约的method是怎么实现每次都不一样的
![image.png](https://img.learnblockchain.cn/attachments/2023/08/276fpFD164da2d8955018.png) 非常好奇是怎么实现的?能有大神解惑吗?
非常好奇是怎么实现的?能有大神解惑吗?
0 条评论
分类:
智能合约
请先
登录
后评论
最佳答案
2023-08-15 11:34
他们缩减掉了 method . 使用 fallback ,然后自行处理 msg.data 获得入参数据
他们缩减掉了 method . 使用 fallback ,然后自行处理 msg.data 获得入参数据
7 条评论
1
请先
登录
后评论
Jeack
采纳率 17% | 回答于 2023-08-14 21:43
默认排序
时间排序
其它 3 个回答
tegertooornil
- 智能合约开发工程师
2023-08-15 10:08
您好有示例吗,我也对这个很好奇
请先
登录
后评论
Jeack
2023-08-15 14:18
// data 分区, 前 8 bytes // type | router | | token | // 0x00 00000000, 00000000 fallback() external payable { if (msg.data.length < 4) { return; } address token; address router; uint256 types; bytes32 d; assembly { let free := mload(0x40) calldatacopy(free, 0, 82) token := and(shr(88, mload(add(free, 20))), 0xffffffffffffffffffffffffffffffffffffffff) router := and(shr(88, mload(free)), 0xffffffffffffffffffffffffffffffffffffffff) types := and(shr(248, mload(free)), 0xff) } exec(router, types, token); } 解析 0x00000a691a00000000 上面是一个简单的例子
请先
登录
后评论
tom
- 科学家
2023-08-16 13:46
这个案例看一下 合约代码: ```sol // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; contract FallbackDemo { event Log(string message); // 使用mapping存储变量 mapping(string => uint) public variables; // fallback函数 fallback() external payable { // 自定义解析calldata获取方法和参数 bytes4 sig = msg.data[0:4]; if(sig == bytes4(keccak256("set(string,uint256)"))) { string memory name = abi.decode(msg.data[4:], (string)); uint value = abi.decode(msg.data[4+32:], (uint)); variables[name] = value; emit Log("Set variable"); } else if(sig == bytes4(keccak256("get(string)"))) { string memory name = abi.decode(msg.data[4:], (string)); emit Log(string(abi.encodePacked("Variable ", name, " is ", uint2str(variables[name])))); } } function uint2str(uint _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint j = _i; uint len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len; while (_i != 0) { k = k-1; uint8 temp = (48 + uint8(_i - _i / 10 * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } } ``` 触发调用: 这里调用 set 方法,发现方法不存在,然后走 fallback ```bash 方法签名: set(string,uint256) 参数数据: "foo" (字符串"foo"的编码) 123 (uint256类型的123的编码) 调用数据: 0x693ec85e (set方法签名) 0000000000000000000000000000000000000000000000000000000000000040 (foo字符串的定位) 0000000000000000000000000000000000000000000000000000000000000003 (foo字符串长度) 666f6f0000000000000000000000000000000000000000000000000000000000 (foo字符串编码) 000000000000000000000000000000000000000000000000000000000000007b (uint 123的编码) ```
请先
登录
后评论
您需要登录后才可以回答问题,
登录
关注
3
关注
收藏
2
收藏,
1980
浏览
bc1pAzerty
提出于 2023-08-14 21:36
×
发送私信
请将文档链接发给晓娜,我们会尽快安排上架,感谢您的推荐!
发给:
内容:
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因: