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

栏目: 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 )
  • 分类:以太坊

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

查看所有标签

猜你喜欢:

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

群智能算法及其应用

群智能算法及其应用

高尚 / 中国水利水电出版社 / 2006-5 / 25.00元

《群智能算法及其应用》系统地描述了蚁群算法和粒子群优化算法的理论和实现技术及其应用,简单地介绍了鱼群算法。《群智能算法及其应用》着重强调各种算法的混合,讨论了蚁群算法与模拟退火算法的混合、蚁群算法与遗传算法的混合、蚁群算法与混沌理论混合、模拟退火算法、遗传算法与粒子群优化算法混合、混沌理论与粒子群优化算法的混合以及蚁群算法与粒子群优化算法的混合。书中还讨论了群智能算法在旅行商问题、武器一目标分配问......一起来看看 《群智能算法及其应用》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具