546

如何实现一个定制的智能合约地址

 5 years ago
source link: https://huoding.com/2018/09/24/695?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我学习智能合约的一个主要途径就是在 DappRadar 看各个热门应用的源代码,前些天我在看   dice2win 的时候发现一个有趣的现象:虽然它自从上线以来已经多次部署过智能合约,不过让人好奇的是这些地址有一个特点,都有一个和名字很像的 「D1CE」前缀(因为的地址是十六进制的,所以字母 I 被改为了数字 1)。

如何实现呢,其实 ethereum 源代码里已经给出 答案

func CreateAddress(b common.Address, nonce uint64) common.Address {
    data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
    return common.BytesToAddress(Keccak256(data)[12:])
}

也就是说,合约地址完全是由 address 和 nonce 决定的,如果我们希望用一个全新的账户来部署合约,那么当它第一次部署的时候,nonce 必然是 0,于是乎可以推断合约地址完全是由 address 决定的,顺着这个思路,我们只要不断生成新的 address,然后判断它们第一次部署的合约地址是否满足定制的 pattern 即可,附上 golang 源代码:

package main

import (
    "encoding/hex"
    "flag"
    "fmt"
    "regexp"
    "sync"
    "sync/atomic"

    "github.com/ethereum/go-ethereum/crypto"
)

var (
    concurrency = flag.Int("c", 10, "concurrency")
    number      = flag.Int64("n", 1, "number")
    pattern     = flag.String("p", "", "pattern")
)

func init() {
    flag.Parse()
}

func main() {
    var wg sync.WaitGroup

    wg.Add(*concurrency)

    reg := regexp.MustCompile("^0x" + *pattern)
    nonce := uint64(0)

    for i := 0; i < *concurrency; i++ {
        go func() {
            defer wg.Done()
            run(reg, nonce)
        }()
    }

    wg.Wait()
}

func run(reg *regexp.Regexp, nonce uint64) {
    for *number > 0 {
        key, _ := crypto.GenerateKey()
        address := crypto.PubkeyToAddress(key.PublicKey)
        contract := crypto.CreateAddress(address, nonce).Hex()

        if !reg.MatchString(contract) {
            continue
        }

        if atomic.AddInt64(number, -1) < 0 {
            break
        }

        privateKey := hex.EncodeToString(key.D.Bytes())

        fmt.Printf("Contract:\t%s\nAddress:\t%s\nPrivateKey:\t%s\n\n",
            contract,
            address.Hex(),
            privateKey,
        )
    }
}

编译后,当执行命令行的时候,指定你想要的 pattern 即可,一旦匹配成功,我们就可以通过生成的账户来部署合约了,不过在部署前你需要确保账户里有足够的以太来支付部署费用。我在 ropsten 测试网络部署了一个地址前缀定制为 ABCD 开头的 合约

vE7B7vf.png!web

contract

友情提示:定制前缀长度不太长的话,应该很快会有结果,否则,慢慢等吧…


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK