Skip to content

Instantly share code, notes, and snippets.

@Hero-Development
Last active June 30, 2022 17:47
Show Gist options
  • Save Hero-Development/ee67fd36b8a8812b5e4681437ddc6a8e to your computer and use it in GitHub Desktop.
Save Hero-Development/ee67fd36b8a8812b5e4681437ddc6a8e to your computer and use it in GitHub Desktop.
Hardhat unit test showing how to load the signer's private key, arrange struct data, and sign it
const { assert } = require("hardhat");
const SignedData2B = artifacts.require( 'contracts/SignedData2B.sol' );
const Web3 = hre.Web3;
const accounts = [];
let owner, signedData;
contract( 'Step2b', async function( accts ){
owner = accts.shift();
console.info({ owner });
accounts.push( ...accts );
console.info( accounts );
it( "should deploy contracts", async () => {
signedData = await SignedData2B.new();
console.info({ 'Step2b.address': signedData.address });
});
})
describe("Signature Test", function(){
it( "test balances", async () => {
//Imagine configuring this API in Express or Vercel
//1) load the private key during startup...
const web3 = new Web3();
const PRIVATE_KEY = '0xf7af023b9220a31d5b6cf1ae098c0ec9ad11a53e305ac6f344c9bddbbf876d3d';
const signer = web3.eth.accounts.privateKeyToAccount( PRIVATE_KEY );
//2) when a request comes in, create an object that matches our struct (@see SignedData2B.sol)
const mintParams = {
id: 718,
quantity: 2,
expires: Math.round( Date.now() / 1000 ) + 60
};
//3) now convert the data into the Solidity format
//Again, @see SignedData2B.sol to ensure the properties and types match
const data = web3.eth.abi.encodeParameter({
'MintParams': {
id: 'uint256',
quantity: 'uint256',
expires: 'uint32'
}
},
mintParams
);
//4) Create a hash from the contract, minter, and the data (@see SignedData-2a.sol)
const hash = Web3.utils.soliditySha3(
{ type: 'address', value: signedData.address },
{ type: 'address', value: accounts[0] },
{ type: 'bytes', value: data },
);
//5) generate the signature
const signatureObject = signer.sign(hash);
console.log( signatureObject );
/*
{
message: '0xa52e5ce8c315bd9d272cc83ba058a2a98eb1d69d0c8eb40237f08619421c05bc',
messageHash: '0x71ab6d3d0fb95e97dbb25814d16de699850b76ec15c2570588e012a83c0e579b',
v: '0x1b',
r: '0x265d41ec53ecaf101316f9894ba79e671cbd70c228becd04ec4209840acbc375',
s: '0x5f438bce316959f4d84f4607059737d2a4a501da835401718f4723db688d011b',
signature: '0x265d41ec53ecaf101316f9894ba79e671cbd70c228becd04ec4209840acbc3755f438bce316959f4d84f4607059737d2a4a501da835401718f4723db688d011b1b'
}
*/
const expectedSigner = web3.eth.accounts.recover( hash, signatureObject.signature );
assert.equal( expectedSigner, signer.address );
//If this was an API, you would send the mintParams and signature in the API response
//Then your browser would send them in the transaction parameters
await signedData.presale( mintParams, signatureObject.signature, {
from: accounts[0],
value: Web3.utils.toWei( '0.02' )
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment