Transactions relay from Nodejs Backend

Introduction

Meta transactions are based on message signing. A smart contract is deployed with the public address of an EOA as parameter.

The contract will be able to execute transactions on behalf of this EOA only. The owner of the EOA will have to generate a message containing the information of the transaction he wants to execute and sign the message with the EOA.

Deploy a relayable identity smart contract

Use Rockside API to deploy an identity that can relay your transactions (i.e. smart contract for your EOA account):

curl-XPOST\
2 https://api.rockside.io/ethereum/ropsten/contracts/relayableidentity \
3 -H 'apikey: YOUR_API_KEY' \
4 -d '{"account": "YOUR_EOA_PUBLIC_ACCOUNT"}'

You will get:

1{
2 "address": "0x60d44d28c826cff5d05ee57526e20103cdac1c9a"
3 "transaction_hash":"0xa51fdb4b79c45fbe9bf6df5a822814f6ad47bf9dfad4bb2b"
4}

Keep the relayable identity contract address, you will need it to send transactions.

Get the nonce for your EOA on your relayable identity

To avoid replay attacks, the relayable identity manages a nonce for each authorized EOA.

To retrieve the nonce call the Rockside API:

curl -X POST \
https://api.rockside.io/ethereum/ropsten/contracts/relayableidentity/RELAYABLE_CONTRACT_ADDRESS/nonce \
-d '{"account":"PUBLIC_ADDRESS_OF_YOUR_EOA"}'\
-H 'Content-Type: application/json' \
-H 'apikey: YOUR_APIKEY'

You should get:

{
"nonce": "0"
}

Create and sign your transaction message

We will use a small nodejs program to generate the signature of the transaction message.

Create a new project with npm:

npm init

You will need ethereumjs-util and ethereumjs-abi, so install the following:

npm install ethereumjs-util -save
npm install eth-sig-util -save

In your index.js file add the following code and replace values for "YOUR_EOA_PRIVATE_KEY" and "YOUR_CONTRACT_ADDRESS" and the correct nonce value.

var ethUtil = require('ethereumjs-util')
var sigUtil = require('eth-sig-util')
const privateKey = new Buffer("YOUR_EOA_PRIVATE_KEY", "hex")
const signerAddressBuffer = ethUtil.privateToAddress(privateKey);
const signerAddress = ethUtil.bufferToHex(signerAddressBuffer)
console.log('EOA Address :', signerAddress)
var identityAddress = 'YOUR_CONTRACT_ADDRESS'
var destinationAddress = '0x2c68bfBc6F2274E7011Cd4AB8D5c0e69B2341309'
var transactionValue = '0x0'
var transactionData = []
var idenityNonce = 0 //THE NONCE FOR YOUR EOA on the identity
const EIP712Domain = [
{ type: "address", name: "verifyingContract" },
{ type: "uint256", name: "chainId" }
]
const txMessageType = [
{ type: "address", name: "signer" },
{ type: "address", name: "to" },
{ type: "uint256", name: "value" },
{ type: "bytes", name: "data" },
{ type: "uint256", name: "nonce" }
]
const domainData = {
verifyingContract: idenitityAddress,
chainId: 3
};
var txMessage = {
signer: signerAddress,
to: destinationAddress,
value: transactionValue,
data: transactionData,
nonce: identityNonce
};
const txMessageData = {
types: {
EIP712Domain: EIP712Domain,
TxMessage: txMessageType,
},
domain: domainData,
primaryType: "TxMessage",
message: txMessage
};
const sig = sigUtil.signTypedData(privateKey, { data: txMessageData })
console.log("SIGNATURE: "+sig)

By running the code youwill get:

node index.js
EOA Address : 0x2c68bfbc6f2274e7011cd4ab8d5c0e69b2341309
SIGNATURE: 0x0944d98fb85729bf4692c9ee9c8221b70a33a19da074648d4e6a811861fc94e35bd715541319a437cb3ef1a2f13aa4ddf76c55297093682da86fca6fdd33a1191b

Use Rockside to Relay your transaction

Call Rockside API to relay your transaction:

curl -X POST 'https://api.rockside.io/ethereum/ropsten/contracts/relayableidentity/RELAYABLE_CONTRACT_ADDRESS/relayExecute' \
-d '{"from":"SIGNER_ADDRESS", "to":"DESTINATION_ADDRESS", "value":"0x0", "signature":"SIGNATURE_OF_YOUR_MESSAGE"}' \
-H 'Content-Type: application/json' \
-H 'apikey: YOUR_APIKEY'

You will get the hash of your transaction that you can follow on Etherscan:

{"transaction_hash":"0xb1b5ec87c6b24e3f3bc389b2e1dca4d0c8bcbd52ba153508b89342a83f0fa977"}

.