Loading...
Hello and welcome to this tutorial on how to send arguments while deploying a smart contract on VeChain !
VeChain is a blockchain platform that provides a secure and transparent environment for decentralized applications (DApps) to run on. Smart contracts are one of the main components of the VeChain ecosystem, allowing developers to create and execute self-executing contracts that automate business processes.
In this tutorial, we'll walk through the steps to deploy a smart contract on VeChain and pass arguments during the deployment process. By the end of this tutorial, you'll be able to deploy your own custom smart contracts with arguments on the VeChain blockchain.
So, if you're ready to dive into the world of VeChain smart contract development, let's get started 👉
The first important thing is to have a smart contract constructor that accepts arguments. Here is an example of a smart contract that we will be deploying which includes a constructor function with arguments -
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MyContract {
uint256 public myValue;
bool flag;
constructor(uint256 _initialValue, bool val) {
myValue = _initialValue;
flag = val;
}
function check_vals() view public returns(uint256, bool){
return (myValue, flag);
}
}
To deploy our smart contract, we'll need two pieces of information: the bytecode of the contract and the encoded parameters of the constructor function. Here's what they look like:
Bytecode = 0x6080604...8110033 (always need to add "0x" before the bytecode when sending it in tx)
0x0000000000000000000000000000000000000000000000000000000000000022
Here we encoded the number "34"Now that we have both the information pieces, all we have to do is convert both into DATA that we can pass to the VeChain blockchain as instructions. You can check out how the smart contract deployer is built in this smartbook for more details.
Let’s say we have to send “34” and “true” as arguments while deploying the smart contract but the thing is we can’t send arguments directly (34 and true) while deploying a smart contract.
We need to make these arguments compatible with the bytecode so that the arguments are properly formatted and can be interpreted by the Blockchain VM during contract deployment and interaction. We do this by encoding these parameters and then we infuse these encoded parameters with the smart contract bytecode to create a final bytecode which we will send as DATA to the blockchain.
Final_DATA = Bytecode + Encoded_Parameters
We already have the bytecode of the contract so now let's encode the parameters that we have to pass to the constructor, for that we need to do the following things -
1. Adding web3js - To encode an ABI or Arguments you will need web3.js library (you can do it with other methods but its little complex) which we can add via CDN as follows :
<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/3.0.0-rc.5/web3.min.js" integrity="sha512-jRzb6jM5wynT5UHyMW2+SD+yLsYPEU5uftImpzOcVTdu1J7VsynVmiuFTsitsoL5PJVQi+OtWbrpWq/I+kkF4Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
2. encode_ABI() - We will create a function that will return to encoded arguments for the constructor,
const contract_abi = // PUT CONTRACT ABI HERE
function encode_ABI() {
const web3 = new Web3();
const constructor_abi = contract_abi.find(({ type }) => type === "constructor");
let inputTypes = constructor_abi.inputs.map(input => input.type);
let inputValues = document.getElementById('arg_int').value;
inputValues = inputValues.split(',');
const encoded_args = web3.eth.abi.encodeParameters(inputTypes, inputValues);
return encoded_args.slice(2)
}
Let’s Understand the above code line by line 👉🏻
Our final aim is to use web3.eth.abi.encodeParameters( inputTypes, inputValues ) function which will give us encoded arguments, which then we will use to infuse with bytecode to create our data value to send on VeChain blockchain for deploying our smart contract with arguments.
This function accepts two arguments, the first is data types of arguments in the form of an array, and the other is values to pass as arguments in the form of an array, as follows -
arg1 -> ["uint256", "bool"]
arg2 -> ["34", "true"]
Getting InputTypes of constructor Parameters
{
"inputs": [
{
"internalType": "uint256",
"name": "_initialValue",
"type": "uint256"
},
{
"internalType": "bool",
"name": "val",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
}
inputTypes -> ["uint256", "bool"]
Getting inputValues for constructor Arguments
inputValues -> ["34", "true"]
Now that we have got the values for both arguments to get encoded arguments, after feeding these values into web3.eth.abi.encodeParameters(inputTypes, inputValues) function we will receive encoded arguments, let’s store it in encoded_args variable.
encoded_args will have value as follows -
encoded_args -> 0x00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000001
Finally, we have our parameters encoded, let’s remove “0x” from it and return the encoded parameters.
Now we send this data in the transaction function as follows -
async function deploy_contract() {
const encoded_args = encode_ABI()
const bytecode = document.getElementById("_bytecode").value;
arged_bytecode = '0x' + bytecode + encoded_args; // NOTE : REMOVE 0x if your bytecode already starts with '0x'
const resp = await connex.vendor
.sign('tx', [{ value: 0, data: arged_bytecode, to: null }])
.comment('Deploy contract')
.request()
document.getElementById("res").innerHTML = resp.txid
}
Here we are calling encode_ABI() function to get encoded Parameters then we are combining it with Bytecode to create our DATA parameter value to send to VeChain for deployment.
You can check out this smartbook for more details about deploy_contract() function and it's working here
This is our complete JS code,
// <!-- ! Connecting with wallet
const connex = new Connex({
node: 'https://vethor-node-test.vechaindev.com',
network: 'test'
})
//PUT ABI HERE
const contract_abi = [ { } ] // -- ABI GOES HERE --
function encode_ABI() {
const web3 = new Web3();
const constructor_abi = contract_abi.find(({ type }) => type === "constructor");
let inputTypes = constructor_abi.inputs.map(input => input.type);
let inputValues = document.getElementById('arg_int').value;
inputValues = inputValues.split(',');
const encoded_args = web3.eth.abi.encodeParameters(inputTypes, inputValues);
return encoded_args.slice(2)
}
async function deploy_contract() {
const encoded_args = encode_ABI()
const bytecode = document.getElementById("_bytecode").value;
arged_bytecode = '0x' + bytecode + encoded_args; // NOTE : REMOVE 0x if your bytecode already starts with '0x'
const resp = await connex.vendor
.sign('tx', [{ value: 0, data: arged_bytecode, to: null }])
.comment('Deploy contract')
.request()
document.getElementById("res").innerHTML = resp.txid
}
I have uploaded the complete web application with an HTML page and server setup on GitHub, You can clone the project from here and follow these steps -
npm install
commandnode index.js
command.
Platform also has a complete certification course to help you start building on Vechain, checkout here -> Introduction to VeChain
You will find multiple smartbooks related to VeChain and others on DApp World itself (smartbooks), and If you are interested in sharing your awesome knowledge and expertise about blockchain and web3 by writing tutorials and articles, join Web3 Authors ✍ on DApp World, Apply here 👈