Solidity——Bytecode文件结构

SolidityBytecode文件结构

智能合约Demo

pragma solidity ^0.4.25;
contract Demo{
	uint public value1 = 0;
	uint public value2 = 0;
	
	function A(uint a) public returns(uint){
	    value1 += a;
	    return value1;
	}
	function B(uint b) public{
	    value2 += A(b);
	}
}

上面是一个智能合约DEMO,用REMIX部署DEMO合约,获得Bytecode文件。
Remix界面

点击右侧Details ,如下图:
字节码

Bytecode文件

Bytecode由两部分构成。第一部分的.code包含了一些smart contract初始化的代码,比如构造函数,state variable(全局变量)的赋值等操作。区块链上,这些都是EOA在部署合约时就执行完成的,在区块链浏览器,是无法看到这部分的代码的。从.data开始,是smart contract的runtime bytecode,也就是在区块链上保存的合约的bytecode。想要获得该部分的bytecode,可以安装solidity,通过命令 solc --bin-runtime demo.sol获得。
Remix的结构有点不太一样,是由若干个tag组成的,每个tag由若干个基本块组成。以JUMPDEST或者结束指令(RETURN,REVERT,STOP)划分。.code部分是Bytecode的入口,这部分的指令包含了所有能够被外部调用的函数的函数签名和跳转pc值。
.code
上面的5个框分别是该合约的5个跳转函数。可能会奇怪合约就2个函数,为何会有5个可跳转函数。这5个跳转函数分别是:1. fallback(回退函数),2个public全局变量,2个public函数。
首先解释一下fallback函数,在EVM中,fallback函数是唯一一个未命名的函数,可以发现其他4个框前面都有一个函数签名,如第二个框的3033413B,只有fallback function没有函数签名。因此如果我们调用了一个合约中没有的函数,没有一个函数签名能满足,接下来的四个框都不会满足跳转条件,因此会通过fall to的形式执行tag1,tag1也就是fallback函数的开始位置。
接下来说一下什么是函数签名。函数签名是一个4byte的hash值,用来唯一标识smart contract中的函数。它是通过sha3(“functionName(type1, type2)”) 或者 keccak256(“functionName(type1, type2)”),取前4bytes得到的。也就是说该函数签名只与函数名,函数类型有关,与函数内容无关
总结一下.code部分,该部分包含了合约能调用的所有函数的跳转地址,从上图中提现就是tag1-5。 tag 1-5分别是5个函数的起始位置。

Bytecode执行流程

下面用函数B为例,解释一下EVM的bytecode是如何跳转的:
在这里插入图片描述
在这里插入图片描述

  1. 要调用函数B,首先EVM会接受到函数签名(DAC0EB07),在.code部分中,跳转到tag 5
  2. tag 5是函数B的开始部分,tag 5中有一个JUMPI,假设跳转条件满足,EVM会跳转到tag 15,如果不满足条件,则会执行PUSH, DUP1, REVERT。 REVERT是终止指令。tag 15上通常是用来判断一个函数是否是payable的。比如CALLVALUE指令会得到transacation是否发了Ether,如果发了ether,ISZERO的结果就会是false,因此不会执行跳转
  3. 执行tag 15, 执行到最后有一个JUMP指令,会从EVM stack读出一个值, 上一个push到stack的值是tag 17,因此跳转到tag 17
  4. 执行tag 17,同tag 15,tag17最后的tag 15会使pc跳转到tag14(tag 14也就是函数A的函数体部分)
  5. 执行tag 14,执行到最后有一个JUMP指令,这时JUMP指令读到的是tag 17中push的tag 20
  6. 执行tag 20, tag20最后的JUMP指令,执行的是tag15中的push tag 16, 因此会跳转到tag 16。
  7. 执行tag 16,执行到stop指令,程序终止。
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: soliditybytecode是经过编译生成的字节码,其中包含了合约的二进制代码和一些元数据。如果你已经拥有了bytecode,那么你可以使用solidity的官方工具solc将bytecode转换成abi。在命令行中运行以下命令即可: ``` solc --abi <your_contract_bytecode> ``` 在这里,`<your_contract_bytecode>`是你的合约字节码。执行上述命令后,会生成一个JSON格式的abi文件,其中包含了你的合约的函数名、参数类型、返回类型等信息。 ### 回答2: 在Solidity中,字节码(bytecode)是由智能合约源代码编译生成的机器码指令序列,而ABI(Application Binary Interface)是用于与合约进行交互的接口描述。反编译字节码以获取ABI的过程如下所示: 1. 使用Solidity编译器(solc)将Solidity源代码编译为字节码。这可以通过命令行工具(solc)或使用Solidity插件进行。 2. 获取编译后的字节码(bytecode)。一般来说,编译器会生成合约的部署字节码和运行时字节码。部署字节码用于在区块链上创建新的合约实例,而运行时字节码用于执行合约中的方法。 3. 使用反编译工具将字节码反编译为汇编代码。有几种工具可以实现这一步骤,如Etherscan的工具,它可以将部署字节码和运行时字节码转换为可读的汇编代码。 4. 根据反编译的汇编代码推导出ABI。反编译的汇编代码将显示每个函数的入口点和参数类型等信息。根据这些信息,可以手动创建ABI,或使用相关工具从汇编代码中提取并自动生成ABI。 需要注意的是,由于编译器的优化等因素,反编译得到的汇编代码可能不完全准确,某些信息(如内部函数、变量名)可能会丢失。因此,在实际应用中,最好使用在编译阶段生成的ABI,而不是依赖于反编译出来的版本。 ### 回答3: 要反编译 Solidity 的字节码(bytecode)以获取 ABI(应用程序二进制接口),我们可以使用一些工具和步骤: 1. 使用 Solidity 编译器将智能合约源代码编译为字节码。例如,使用 solc 命令行工具:`solc --bin <contract_filename.sol>`。这将生成合约的字节码文件。 2. 将字节码转换为可读格式。字节码通常是以十六进制表示的。我们可以使用 Solidity 的库函数来将其转换为可读的格式。在 Solidity 中使用以下函数:`bytes memory bytecode = hex"字节码"`。 3. 使用反编译工具将字节码转换为 ABI。目前,有一些可用的工具可以帮助我们将 Solidity 字节码转换为 ABI。 - Solidity Assembly 是一种受到 EVM 指令集影响的低级语言。您可以使用 Solidity Assembly 编写代码并将其转换为 ABI。示例代码如下: ``` pragma solidity ^0.8.0; contract BytecodeParser { function getABI(bytes memory _bytecode) public pure returns (string[] memory) { assembly { let ptr := add(_bytecode, 0x20) let length := mload(_bytecode) let result := mload(0x40) // allocate memory for the ABI mstore(result, 0x20) // set length of the array to 1 mstore(add(result, 0x20), length) // store the length of the bytecode as the first element mstore(add(result, 0x40), ptr) // store the bytecode as the second element return(result, 0x60) } } } ``` - Mythril 是一个开源的智能合约扫描工具,也可以用于反编译 Solidity 字节码。安装 Mythril 并使用以下命令:`myth -x <Bytecode_File_Path>`。 - Remix IDE 是一个具有反编译功能的 Solidity 开发环境。在 Remix IDE 中,您可以上传字节码文件并选择反编译功能以获取 ABI。 请注意,由于 Solidity 字节码是通过编译过程中的优化生成的,所以在某些情况下,反编译出的 ABI 可能不完全准确。因此,在实际使用过程中,最好通过查看合约的源代码来获取准确的 ABI。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值