抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

calAddressByCreate2

1. 【使用python】

这里是借鉴张学长的🤣

1.1 安装web3库

1
pip install web3

1.2 计算代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from web3 import Web3
# value of your address(this)
# must delet 0x
# example:0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
address = "5B38Da6a701c568545dCfcB03FcB875f56beddC4"

# 固定常量 0xff
const_value = "0xff"

# 将前两个值拼接起来
s1 = const_value + address

# 这个为代部署合约的字节码,可以通过keccak256(abi.encodePacked(bytecode))来计算
s3 = ''


i = 0
while(True):
salt = hex(i)[2:].rjust(64, '0')
s = s1+salt+s3
hashed = Web3.keccak(hexstr=s)
hashed_str = ''.join(['%02x' % b for b in hashed])
if 'badc0de' in hashed_str[24:]:
print(salt,hashed_str)
break
i += 1
print(hashed)

python暂时没学好,等过段时间再回来解读

2.【使用ethereumjs】

2.1 安装ethereumjs库

1
npm install ethereumjs-util

2.2 计算代码

bytecode的值前要填 0x

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const eth = require('ethereumjs-util');

// a. 常数
const const_num = "0xFF";

// b. 创建者地址(合约地址)
// 一般情况下是: address(this)
// 拼接的时候不能包含 `0x`
const contract_add = "0xf2B1114C644cBb3fF63Bf1dD284c8Cd716e95BE9";

// 3. 拼接
const str1 = const_num + contract_add.slice(2,contract_add.length);

// 4. 代部署合约的字节码的hash值
const bytecode = "0x608060405234801561000f575f80fd5b506103478061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063380c7a6714610038578063b2fa1c9e14610042575b5f80fd5b610040610060565b005b61004a61009d565b6040516100579190610219565b60405180910390f35b610069336100ad565b610071575f80fd5b61007a33610144565b610082575f80fd5b60015f806101000a81548160ff021916908315150217905550565b5f8054906101000a900460ff1681565b5f7f736d6172780000000000000000000000000000000000000000000000000000008273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401602060405180830381865afa158015610118573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061013c9190610269565b149050919050565b5f808260601b90505f6f0badc0de00000000000000000000000090505f6f0fffffff00000000000000000000000090505f5b60228110156101f257826bffffffffffffffffffffffff19168285166bffffffffffffffffffffffff1916036101b35760019450505050506101fa565b6004826bffffffffffffffffffffffff1916901b91506004836bffffffffffffffffffffffff1916901b925080806101ea906102ca565b915050610176565b505f93505050505b919050565b5f8115159050919050565b610213816101ff565b82525050565b5f60208201905061022c5f83018461020a565b92915050565b5f80fd5b5f819050919050565b61024881610236565b8114610252575f80fd5b50565b5f815190506102638161023f565b92915050565b5f6020828403121561027e5761027d610232565b5b5f61028b84828501610255565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f819050919050565b5f6102d4826102c1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361030657610305610294565b5b60018201905091905056fea26469706673582212206e6c1e4a56c3130f88f4149292cceaff6d90339aeaa3f29562e40adef7c39b2a64736f6c63430008140033";

let bytecodeToHash = eth.bufferToHex(eth.keccakFromHexString(bytecode));
// 去掉0x
bytecodeToHash = bytecodeToHash.slice(2, bytecodeToHash.length);


let salt = 0;
while (true) {
// 1. Convert i to hex, and it pad to 32 bytes:
// 1. 将i转为16进制的字符串,padStart右对齐,用 0 补齐32bytes
// var saltToBytes = salt.toString(16).padStart(64, '0');
let saltToHex = "0x" + salt.toString(16);

let saltToHash = eth.bufferToHex(eth.keccakFromHexString(saltToHex));
saltToHash = saltToHash.slice(2, saltToHash.length);

// 2. Concatenate this between the other 2 strings
// 2. 将 string1 saltToBytes string2三个字段的值拼接在一起
var concatString = str1.concat(saltToHash).concat(bytecodeToHash);

/**
* 3. Hash the resulting string
* 对上行代码的 concatString 进行hash:
* eth.keccakFromHexString() 是 Ethereum.js 库中的一个方法,
* 用于对一个十六进制字符串进行 Keccak-256 哈希运算返回值类型为 Buffer
*
*/
var hashed = eth.bufferToHex(eth.keccakFromHexString(concatString));

// 这个不对 因为 eth.keccak256()的参数不支持string类型,只支持Buffer类型
// var hashed = eth.bufferToHex(eth.keccak256(concatString))

// 4. Remove leading 0x and 12 bytes
// 5. Check if the result contains badc0de
// hashed.slice(26,20)
if (hashed.slice(26, hashed.length).includes('badc0de')) {
console.log(`salt = 0x${salt.toString(16)}`);
console.log(`address = 0x${hashed.slice(26, hashed.length)}`);
break;
}

salt++;
}

3. 【ethersjs】

3. 1 安装ethersjs库

1
npm install ethers

3.2 计算代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { ethers } from "ethers"

/**
* create2 计算合约地址所需要的四个值
*
* 1. 0xFF:一个常数,避免和CREATE冲突
2. 创建者地址
3. salt(盐):一个创建者给定的数值
4. 待部署合约的字节码(bytecode)
*/

// 1. 常数
const const_num = "0xFF";

// 2. 创建者地址(合约地址)
// 一般情况下是: address(this)
// 拼接的时候不能包含 `0x`
const contract_add = "0xf2B1114C644cBb3fF63Bf1dD284c8Cd716e95BE9";

// 3. 拼接
let str1 = const_num + contract_add.slice(2,contract_add.length);

// 4. 代部署合约的字节码的hash值
const bytecode = "0x608060405234801561000f575f80fd5b506103478061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063380c7a6714610038578063b2fa1c9e14610042575b5f80fd5b610040610060565b005b61004a61009d565b6040516100579190610219565b60405180910390f35b610069336100ad565b610071575f80fd5b61007a33610144565b610082575f80fd5b60015f806101000a81548160ff021916908315150217905550565b5f8054906101000a900460ff1681565b5f7f736d6172780000000000000000000000000000000000000000000000000000008273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401602060405180830381865afa158015610118573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061013c9190610269565b149050919050565b5f808260601b90505f6f0badc0de00000000000000000000000090505f6f0fffffff00000000000000000000000090505f5b60228110156101f257826bffffffffffffffffffffffff19168285166bffffffffffffffffffffffff1916036101b35760019450505050506101fa565b6004826bffffffffffffffffffffffff1916901b91506004836bffffffffffffffffffffffff1916901b925080806101ea906102ca565b915050610176565b505f93505050505b919050565b5f8115159050919050565b610213816101ff565b82525050565b5f60208201905061022c5f83018461020a565b92915050565b5f80fd5b5f819050919050565b61024881610236565b8114610252575f80fd5b50565b5f815190506102638161023f565b92915050565b5f6020828403121561027e5761027d610232565b5b5f61028b84828501610255565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f819050919050565b5f6102d4826102c1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361030657610305610294565b5b60018201905091905056fea26469706673582212206e6c1e4a56c3130f88f4149292cceaff6d90339aeaa3f29562e40adef7c39b2a64736f6c63430008140033";

// 5.1 对bytecode 进行hash运算 这个只能用单引号
// solidityKeccak256(['bytes'],[bytecode]) <=> keccak256(abi.encodePacked(bytecode))
const bytecodeToHash = ethers.utils.solidityKeccak256(['bytes'],[bytecode]);

// 5.2 下面这行代码也行,因为对 bytecode进行紧打包的结果不变
// const bytecodeToHash = ethers.utils.keccak256(bytecode);
// console.log(bytecodeToHash)

// 5. 定义一个盐,以及一个所求字段
let salt = 0;
const value = "badc0de"; // CTF靶场的题

// 遍历出指定值,求出salt
while (true) {
// 将salt转为16进制,用0填充为64位
// let saltToBytes = salt.toString(16).padStart(64, 0).toString();

let saltToHash = ethers.utils.solidityKeccak256(['uint'],[salt]);
saltToHash = saltToHash.slice(2, saltToHash.length);

// 再次拼接 顺序: 常数 创建者地址 盐 字节码的hash值
// bytecodeToHash.slice(2,bytecodeToHash.length): 删除 `0x`
let str2 = str1.concat(saltToHash).concat(bytecodeToHash.slice(2,bytecodeToHash.length));
// 对 str2 进行hash
let hash = ethers.utils.solidityKeccak256(['bytes'] ,[str2]);
// console.log(saltBuffer)

// 先将打包好的str2 转为 utf8的字节数组
// let saltUtf8Bytes = ethers.utils.toUtf8Bytes(str2);

// 将 saltUtf8Bytes 转化为buffer
// let saltBuffer = ethers.utils.arrayify(saltUtf8Bytes);


// 对 saltBuffer 进行hash
// let hash = ethers.utils.keccak256(str2);

//判断 是否满足条件
if (hash.slice(26, hash.length).includes(value)) {
console.log(`salt = 0x${salt.toString(16)}`);
console.log(`address = 0x${hash.slice(26, hash.length)}`);
break;
}

salt++;
}

搭配使用的solidity代码

计算地址:

1
2
3
4
5
6
7
8
9
10
11
    function getCreate2Address(address addToDeploy, uint256 salt, bytes memory bycode) external pure returns(address  result) {
result = address(uint160(uint(
keccak256(abi.encodePacked(
uint8(0xff), // 固定的一个字节的常数 0xff
addToDeploy, //当前合约地址(create2合约地址)
keccak256(abi.encodePacked(salt)), //对盐进行紧打包
keccak256(bycode) //要计算的合约的字节码
))
)));
}
}

4. 推荐使用 ethersjs

评论



政策 · 统计 | 本站使用 Volantis 主题设计