以太坊中如何判断一个地址为合约账户地址

栏目: IT技术 · 发布时间: 4年前

内容简介:本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0x01 以太坊中的两类账户

对以太坊稍微了解一些朋友,应该知道,以太坊中有两类账户,一类是普通的由私钥控制的外部账户,一类是关联有合约代码的合约账户。 ![以太坊地址]( https://upload ...

0x01 以太坊中的两类账户

对以太坊稍微了解一些朋友,应该知道,以太坊中有两类账户,一类是普通的由私钥控制的外部账户,一类是关联有合约代码的合约账户。 以太坊中如何判断一个地址为合约账户地址

但是如果我给你下面两个地址,你知道哪个是外部账户地址,哪个是合约账户地址么? 0x8415A51d68e80aebb916A6f5Dafb8af18bFE2F9d 0x11b314EF962425231150739EF2627FB13214e5Bf

0x02 常用方法

区分的关键是看这个地址有没有与之相关联的代码。 EVM 提供了一个操作码 EXTCODESIZE,用来获取地址相关联的代码大小(长度),如果是外部账号地址,则没有代码返回。因此我们可以使用以下方法判断合约地址及外部账号地址:

function isContract(address addr) internal view returns (bool) {
    uint256 size;
    assembly { size := extcodesize(addr) }
    return size > 0;
  }

如果是在合约外部判断,则可以使用 web3.eth.getCode(),或者是对应的 JSON-RPC 方法 eth_getcode。 getCode() 用来获取参数地址所对应合约的代码,如果参数是一个外部账号地址,则返回 "0x";如果参数是合约,则返回对应的字节码,如下所示:

web3.eth.getCode("0x8415A51d68e80aebb916A6f5Dafb8af18bFE2F9d")
"0x"
web3.eth.getCode("0x11b314EF962425231150739EF2627FB13214e5Bf")
"0x"

什么?两个地址竟然得到同样的结果!!!如果其中一个地址是合约地址的话,不是应该得到合约关联的字节码么?难道两个地址都是外部账户地址?

0x03 未上链的合约地址

哈哈,告诉你吧,上面两个地址中的其中一个地址,是我在链下生成的,代码还没部署到区块链网络中呢,你当然得不到关联代码啦。 合约账户地址是怎么生成的呢?其实有两种生成方式,我是用的比较简单的方式生成的,生成的公式如下:

合约地址 = keccak256(rlp([sender, nonce]))


对应的 java 代码为:

public static String generateAddress(String address, long nonce) {
    byte[] addressAsBytes = Numeric.hexStringToByteArray(address);

    byte[] calculatedAddressAsBytes =
        Hash.sha3(RlpEncoder.encode(
            new RlpList(
                RlpString.create(addressAsBytes),
                RlpString.create((nonce)))));

    calculatedAddressAsBytes = Arrays.copyOfRange(calculatedAddressAsBytes,
        12, calculatedAddressAsBytes.length);
    String calculatedAddressAsHex = Numeric.toHexString(calculatedAddressAsBytes);
    return calculatedAddressAsHex;
  }

调用代码为:

AddressUtils.generateAddress("0x8415A51d68e80aebb916A6f5Dafb8af18bFE2F9d", 18))

这说明什么? 当你通过是否关联有代码来判断一个地址是否是合约账户地址时,心里要明镜似的,一个地址关联有代码,那它肯定是合约地址,如果一个地址没有代码关联,并不能肯定这个地址是外部账户地址还是合约地址。

##0x04 怎么办? 需要判断地址类型的一个常见需求就是只允许外部账户调用我们的合约,不允许合约账户调用我们的合约,满足这个需求,在合约里加上这个判断就可以了:

require(tx.origin == msg.sender)

0x01 以太坊中的两类账户

对以太坊稍微了解一些朋友,应该知道,以太坊中有两类账户,一类是普通的由私钥控制的外部账户,一类是关联有合约代码的合约账户。 以太坊中如何判断一个地址为合约账户地址

但是如果我给你下面两个地址,你知道哪个是外部账户地址,哪个是合约账户地址么? 0x8415A51d68e80aebb916A6f5Dafb8af18bFE2F9d 0x11b314EF962425231150739EF2627FB13214e5Bf

0x02 常用方法

区分的关键是看这个地址有没有与之相关联的代码。 EVM 提供了一个操作码 EXTCODESIZE,用来获取地址相关联的代码大小(长度),如果是外部账号地址,则没有代码返回。因此我们可以使用以下方法判断合约地址及外部账号地址:

function isContract(address addr) internal view returns (bool) {
    uint256 size;
    assembly { size := extcodesize(addr) }
    return size > 0;
  }

如果是在合约外部判断,则可以使用 web3.eth.getCode(),或者是对应的 JSON-RPC 方法 eth_getcode。 getCode() 用来获取参数地址所对应合约的代码,如果参数是一个外部账号地址,则返回 "0x";如果参数是合约,则返回对应的字节码,如下所示:

web3.eth.getCode("0x8415A51d68e80aebb916A6f5Dafb8af18bFE2F9d")
"0x"
web3.eth.getCode("0x11b314EF962425231150739EF2627FB13214e5Bf")
"0x"

什么?两个地址竟然得到同样的结果!!!如果其中一个地址是合约地址的话,不是应该得到合约关联的字节码么?难道两个地址都是外部账户地址?

0x03 未上链的合约地址

哈哈,告诉你吧,上面两个地址中的其中一个地址,是我在链下生成的,代码还没部署到区块链网络中呢,你当然得不到关联代码啦。 合约账户地址是怎么生成的呢?其实有两种生成方式,我是用的比较简单的方式生成的,生成的公式如下:

合约地址 = keccak256(rlp([sender, nonce]))


对应的 java 代码为:

public static String generateAddress(String address, long nonce) {
    byte[] addressAsBytes = Numeric.hexStringToByteArray(address);

    byte[] calculatedAddressAsBytes =
        Hash.sha3(RlpEncoder.encode(
            new RlpList(
                RlpString.create(addressAsBytes),
                RlpString.create((nonce)))));

    calculatedAddressAsBytes = Arrays.copyOfRange(calculatedAddressAsBytes,
        12, calculatedAddressAsBytes.length);
    String calculatedAddressAsHex = Numeric.toHexString(calculatedAddressAsBytes);
    return calculatedAddressAsHex;
  }

调用代码为:

AddressUtils.generateAddress("0x8415A51d68e80aebb916A6f5Dafb8af18bFE2F9d", 18))

这说明什么? 当你通过是否关联有代码来判断一个地址是否是合约账户地址时,心里要明镜似的,一个地址关联有代码,那它肯定是合约地址,如果一个地址没有代码关联,并不能肯定这个地址是外部账户地址还是合约地址。

0x04 怎么办?

需要判断地址类型的一个常见需求就是只允许外部账户调用我们的合约,不允许合约账户调用我们的合约,满足这个需求,在合约里加上这个判断就可以了:

require(tx.origin == msg.sender)

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 6分钟前
  • 阅读 ( 5 )
  • 学分 ( 0 )
  • 分类:以太坊

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

社群营销与运营/互联网+新媒体营销规划丛书

社群营销与运营/互联网+新媒体营销规划丛书

秦阳//秋叶|总主编:秋叶 / 人民邮电出版社 / 2017-5 / 45.00元

《社群营销与运营》共分6章。第1章重点介绍了社群营销的起因、概念、构成、价值和评估模型,引导读者全面认识社群以及社群营销;第2章介绍了如何从无到有、从小到大建设一个社群的手法和注意事项;第3章重点介绍维持社群活跃度的各种技巧;第4章介绍了组织一场社群线下活动五个阶段的执行方案;第5章介绍了如何从无到有、由弱到强地构建社群运营团队;第6章介绍如何正确看待社群商业变现以及社群商业变现的三大模式和四个基......一起来看看 《社群营销与运营/互联网+新媒体营销规划丛书》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具