Skip to content

Instantly share code, notes, and snippets.

@schemar
Last active April 3, 2023 09:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schemar/7e67a5fb881e937d557e61e02cdad4ed to your computer and use it in GitHub Desktop.
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.
/*
* ==========
* 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);
@pooriagg
Copy link

it is incorrect you must use 'import { arrToBufArr, bufArrToArr } from 'ethereumjs-util'' becuz sha3 only acepts Buffers !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment