本文主要介绍以太坊智能合约ABI和EVM字节码
以太坊采用EVM(Ethereum Virtual Machine)作为系统的核心,将solidity编写的智能合约代码编译成EVM字节码和合约ABI,运行对应的智能合约。
本文主要内容:
以太坊使用EVM作为网络的核心组件,需要将高级语言编写的智能合约代码编译成EVM字节码才能运行,EVM字节码是EVM上可执行代码。
Contract ABI 是与 EVM 字节码交互的接口。 例如,如果你想用你的 JavaScript 代码调用智能合约中的一个函数,ABI 就扮演了你的 JavaScript 代码和 EVM 字节码之间的中介角色,以实现相互交互。
EVM 字节码是一种低级编程语言,由高级编程语言(如 solidity)编译而成。
EVM 是一个虚拟机,位于操作系统和应用程序层之间以减轻操作系统的依赖性。 感谢 EVM,以太坊智能合约几乎可以在任何计算机上运行。 如果您是 Java 开发人员,您可以将 JVM(Java 虚拟机)视为相同的机制。 EVM 字节码如下所示。 它不是人类可读的,但机器可读。
608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033
60003560e01c80632e64cec11461003b5780636057361d1461005957
字节码对应着EVM的opcode列表,即操作码。opcode的长度为1个字节也就是最多支持256种opcode。
60 00 = PUSH1 0x00
35 = CALLDATALOAD
60 e0 = PUSH1 0xe0
1c = SHR
80 = DUP1
63 2e64cec1 = PUSH4 0x2e64cec1
14 = EQ
61 003b = PUSH2 0x003b
57 = JUMPI
80 = DUP1
63 6057361d = PUSH4 0x6057361d
14 = EQ
61 0059 = PUSH2 0x0059
57 = JUMPI
这里我们调用了合约的store函数,参数为10。我们使用abi.encodeWithSignature()获得calldata,emit会记录用于测试的calldata。
0x6057361d000000000000000000000000000000000000000000000000000000000000000a
上面就是abi.encodeWithSignature(”store(uint256)”,10)返回的字节码
函数签名就是函数规范化表示的Keccak Hash的前四个字节。
calldata有36个字节,前四个字节对应计算出的store(uint256)函数签名,剩下32个字节对应着传入的uint256参数。
ABI(Application Binary Interface)是两个程序模块之间的接口; 通常,在操作系统和用户程序之间。 在以太坊中,Contract ABI 是一个接口,定义了如何调用智能合约中的函数并取回数据的标准方案。
Contract ABI 专为外部使用而设计,以实现应用程序到合约和合约到合约的交互。 例如,如果你想从你的 dApp 调用智能合约功能,你可以通过 Contract ABI 调用。 合约 ABI 以 JSON 格式表示,如下所示。
[
{
"constant":true,
"inputs":[
],
"name":"testFunc",
"outputs":[
{
"name":"",
"type":"int256"
}
],
"payable":false,
"stateMutability":"pure",
"type":"function"
}
]
Contract ABI 定义函数名称和参数数据类型。 它用于编码 EVM 的合约调用并从交易中读取数据。
对于如何编码和解码合约 ABI 有明确的规范。