预编译合约
今天我们来聊聊以太坊的预编译合约
由于 EVM 是一个基于堆栈的虚拟机,它根据交易所要执行的操作指令内容来计算 gas 消耗,如果计算非常复杂,在 EVM 中执行相关操作指令就会非常低效,而且会消耗大量的 gas。 例如,在 zk-snark 中,需要对椭圆曲线进行加减运算和配对运算。 在 EVM 中执行这些操作是非常复杂和不现实的。所幸以太坊还支持预编译合约。
预编译合约是 EVM 中用于提供更复杂库函数(通常用于加密、散列等复杂操作)的一种折衷方法,这些函数不适合编写操作码。 它们适用于简单但经常调用的合约,或逻辑上固定但计算量很大的合约。 预编译合约是在使用节点客户端代码实现的,因为它们不需要 EVM,所以运行速度很快。 与使用直接在 EVM 中运行的函数相比,它对开发人员来说成本也更低。
在以太坊中已经实现了不少预编译合约了,比如下面这些:
以太坊Geth客户端的预编译合约清单看起来像这样:
var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{},
common.BytesToAddress([]byte{6}): &bn256Add{},
common.BytesToAddress([]byte{7}): &bn256ScalarMul{},
common.BytesToAddress([]byte{8}): &bn256Pairing{},
}