Precompiled
预编译合约提供一种使用C++编写合约的方法,合约逻辑与数据分离,相比于solidity合约具有更好的性能,可以通过修改底层代码实现合约升级。
预编译合约与Solidity合约对比
表名 | 预编译合约 | Solidity合约 |
---|---|---|
地址 | 固定地址,代码中定义 | 部署时确定 |
合约代码 | 数据存储在表中,与合约分离,可升级合约逻辑 | 合约变量和数据存储在MPT树中 |
执行 | C++底层执行,性能更高,可实现并行 | EVM虚拟机,串行执行 |
模块架构
Precompiled的架构如下图所示:
- 区块验证器在执行交易的时候会根据被调用合约的地址来判断类型。地址1-4表示以太坊预编译合约,地址0x1000-0x10000是C++预编译合约,其他地址是EVM合约。
关键流程
- 执行预编译合约时首先需要根据合约地址获取到预编译合约的对象。
- 每个预编译合约对象都会实现
call
接口,预编译合约的具体逻辑在该接口中实现。 call
根据交易的abi编码,获取到Function Selector
和参数,然后执行对应的逻辑。
graph TB Start(开始) —> branch1{预编译合约} branch1 —> |是|op1[根据地址获取合约对象] branch1 —> |否|op2[EVM] op1 —> op3[解析调用函数及参数] op3 —> End(返回执行结果) op2 —> End(返回执行结果)
接口定义
每个预编译合约都必须实现自己的call
接口,接口接受三个参数,分别是ExecutiveContext
执行上下文、bytesConstRef
参数的abi编码和外部账户地址,其中外部账户地址用于判断是否具有写权限。Precompiled
源码。
接口名 | 参数说明 | 接口说明 |
---|---|---|
virtual bytes call(std::shared_ptr<ExecutiveContext> context, bytesConstRef param, Address const& origin = Address()) | context 为区块执行上下文,param 为abi编码的参数,origin 为调用的外部账户地址 | 具体合约接口的实现 |
virtual uint32_t getParamFunc(bytesConstRef param) | param 为abi编码的参数 | 获取调用的函数的Function Select (函数名的sha3的前四个大端字节) |
virtual uint32_t getFuncSelector(std::string const& _functionName) | _functionName 为函数名 | 根据函数名计算Function Select |
virtual bytesConstRef getParamData(bytesConstRef param) | param 为abi编码的参数 | 获取调用函数的具体参数的abi编码 |
当前内容版权归 fisco-bcos.org 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 fisco-bcos.org .