[技术交流] solidity 汇编实现合约地址的计算器

栏目: 编程语言 · 发布时间: 5年前

内容简介:之前由于某种原因想要通过在合约里面计算它创建的下一个合约的地址,用solidity实现起来要消耗6000+ gas,所以就花了点时间用汇编重写了下,效率非常高,有需要的可以拿去gist:

之前由于某种原因想要通过在合约里面计算它创建的下一个合约的地址,用solidity实现起来要消耗6000+ gas,所以就花了点时间用汇编重写了下,效率非常高,有需要的可以拿去

gist: https://gist.github.com/yanche/00f5e7deef4d361eadf3058b2e99a816

pragma solidity ^0.4.24;

library ContractAddrCalculator {
    // author: yanche @ https://github.com/yanche/eth_contract_addr_calc

    // NOTE this program works as long as nonce is less than 33 bytes
    // which is 2**(8*33), almost impossible for a contract to create
    // so many contracts, also uint256 is only 32bytes
    // GAS COST
    // nonce = 1 => 256
    //         0x80 => 389
    //         0x0102 => 429
    // above is example of assembly execution cost, plus 280 other execution cost per tx
    // complaint: 1. the compiler's control flow analysis sucks
    //            2. no opcode for left/right shift, has to use a combination of exp and mul, causes a lot more gas usage
    function calc(address baseAddr, uint256 nonce) public view returns(address addr) {
        assembly {
            // ---------------START: genAddr---------------
            // TODO: load from parameters
            // A N
            baseAddr  /* dup3 */
            nonce     /* dup3 */

                // ---------------START: rlpEncodeNonce---------------
                // N
                dup1
                dup1 /* to fix the compiler bug on stack height calc around "jump" opcode, have to manually maintain the stack height */
                label_not0
                // N N N label_not0
                jumpi
                pop
                pop
                0x80
                1
                // 0x80 1
                label_rlpEnd
                // 0x80 1 label_rlpEnd
                jump
                label_not0:
                // N N
                dup1
                0x7f
                lt
                // N N N>0x7f
                label_rlpGt0x7f
                jumpi
                // N N
                pop
                1
                label_rlpEnd
                // N 1 label_rlpEnd
                jump
                label_rlpGt0x7f:
                // N N
                pop

                    // ---------------START: countStackTopInBytes---------------
                    // push the integer represents the byte count of stack-top number on to stak
                    // example with STACK
                    // 0x00 => 0x00 0x01
                    // 0xf0 => 0xf0 0x01
                    // 0x0102 => 0x0102 0x02
                    // X
                    0
                    // X 0
                    dup2
                    // X 0 X
                    label_loop:
                    swap1
                    // X X 0
                    1
                    add
                    // X X 1
                    swap1
                    // X 1 X
                    256
                    // X 1 X 256
                    swap1
                    // X 1 256 X
                    div
                    // X 1 X>>8
                    dup1
                    // X 1 X>>8 X>>8
                    label_loop
                    // X 1 X>>8 X>>8 label_loop
                    jumpi
                    // X 1 X>>8
                    pop
                    // X 1
                    // ---------------END: countStackTopInBytes---------------

                // N N_len
                swap1
                // N_len N
                dup2
                // N_len N N_len
                dup1
                0x80
                add
                // N_len N N_len rlpNHead
                swap1
                // N_len N rlpNHead N_len
                256
                exp
                // N_len N rlpNHead 256^N_len
                mul
                or
                // N_len rlpN
                swap1
                // rlpN N_len
                1
                add
                // rlpN rlpN_byte_length(N_len + 1)
                label_rlpEnd:
                // rlpN rlpN_byte_length
                // ---------------END: rlpEncodeNonce---------------

            // A rlpN rlpN_len
            dup1
            // A rlpN rlpN_len rlpN_len
            22
            add
            // A rlpN rlpN_len rlp_total_len
            swap3
            // rlp_total_len rlpN rlpN_len A
            dup2
            // rlp_total_len rlpN rlpN_len A rlpN_len
            0xd5 /* 0xd5 = 0xc0 + 21(the byte length of address rlp encoding) */
            // rlp_total_len rlpN rlpN_len A rlpN_len 0xd5
            add
            // rlp_total_len rlpN rlpN_len A rlp_head
            0x0100
            mul
            // rlp_total_len rlpN rlpN_len A rlp_head<<8
            0x94 /* 0x94 = 0x80 + 20 */
            or
            // rlp_total_len rlpN rlpN_len A rlp_head.0x94
            0x010000000000000000000000000000000000000000
            mul
            // rlp_total_len rlpN rlpN_len A rlp_head.0x94<<20bytes
            or
            // rlp_total_len rlpN rlpN_len rlp_head.rlpA
            swap1
            // rlp_total_len rlpN rlp_head.rlpA rlpN_len
            256
            exp
            // rlp_total_len rlpN rlp_head.rlpA 256^rlpN_len
            mul
            or
            // rlp_total_len rlp_head.rlpA.rlpN
            dup2
            0x80
            add
            // rlp_total_len rlp_head.rlpA.rlpN rlp_total_len+0x80
            mstore
            // rlp_total_len
            // memory 0xa0: rlp_head.rlpA.rlpN
            0xa0
            sha3
            // sha3_rlp
            0xffffffffffffffffffffffffffffffffffffffff
            and
            // sha3_rlp(last 20bytes)
            =:addr  /* equivalent to swap1 pop */
            // ---------------END: genAddr---------------
        }
    }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

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

不止情感设计

不止情感设计

陈华 / 电子工业出版社 / 2015-5-21 / 59.00

本书着眼于“设计&心理”两个主要的维度,围绕“创新式思维2.0”(共情—移情—定义—构思—建模—测试)的模式,分析如何“理解一款好的产品设计”、“如何了解用户需求”、“如何从需求来定义产品”的几个步骤,由浅入深地介绍设计师通过洞察和理解用户内在需求来指导产品创新和设计的理念。一起来看看 《不止情感设计》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具