Last active
April 3, 2023 09:21
-
-
Save schemar/7e67a5fb881e937d557e61e02cdad4ed to your computer and use it in GitHub Desktop.
Using web3 and RLP to pre-calculate an address that a contract will have after deployment. Based on address and nonce.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ========== | |
* TypeScript | |
* ========== | |
*/ | |
const nonce = 6; | |
// Forcing type `any`, as web3 sha3 otherwise complains that it only accepts strings. | |
// `RLP.encode()` returns a `Buffer`. | |
// However, converting the buffer to a string first yields the wrong result. The buffer has to | |
// be passed directly into the sha3 function. | |
const encoded: any = RLP.encode( | |
[ | |
account, | |
nonce, | |
], | |
); | |
const nonceHash: string = this.web3.utils.sha3(encoded); | |
// Remove leading `0x` and first 24 characters (12 bytes) of the hex | |
// string leaving us with the remaining 40 characters (20 bytes) that | |
// make up the address. | |
const expectedAddress = this.web3.utils.toChecksumAddress(`0x${nonceHash.substring(26)}`); | |
/* | |
* ========== | |
* JavaScript | |
* ========== | |
*/ | |
// Calculate expected stake address based on key and nonce. | |
// Create new account so that we know the nonce is zero. | |
let account = await web3.eth.personal.newAccount(''); | |
web3.eth.personal.unlockAccount(account, ''); | |
let nonce = 0x00; | |
// Give new account value so it can deploy the contract. | |
await web3.eth.sendTransaction( | |
{ | |
from: accounts[0], | |
to: account, | |
value: 120000000, | |
}, | |
); | |
// Calculate the address based on deploying account address and nonce. | |
let nonceHash = web3.utils.sha3( | |
RLP.encode( | |
[ | |
account, | |
nonce, | |
], | |
), | |
); | |
// Remove leading `0x` and first 24 characters (12 bytes) of the hex | |
// string leaving us with the remaining 40 characters (20 bytes) that | |
// make up the address. | |
let contractAddress = nonceHash.substr(26); | |
// Add the leading `0x` again. | |
contractAddress = '0x' + contractAddress; | |
// Make checksum address (correct capitalization). | |
web3.utils.toChecksumAddress(stakeAddress); | |
// Deploy new contract. Make sure the newly created account deploys | |
// it so that the correct contract address results from the deployment. | |
let contract = await ContractName.new( | |
args, | |
{from: account}, | |
); | |
// Both addresses are equal. | |
console.log(contract.address); | |
console.log(contractAddress); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
it is incorrect you must use 'import { arrToBufArr, bufArrToArr } from 'ethereumjs-util'' becuz sha3 only acepts Buffers !