Setting up Loyalty Tokens on the XDC Network

How to Set Up Loyalty Tokens on the XDC Network

Step 1: Create and deploy a loyalty smart contract on the public network.
Go to https://mycontract.co/ and create a Loyalty Token (Token Contract) after entering details like token name, token symbol, and total token supply.
NOTE: After creating the token contract, deploy it to the XDC Network, download the private key, and store it safely. The safest way to store any private key is, without a doubt, with a paper wallet.
Step 2: Setup XDC full node to get full control over your private key and data backup.
Follow the steps and set up XDC Full Node: https://github.com/XinFinOrg/XinFin-Node​
Step 3: Install Dependencies. Download Nodejs and npm.
Install dependencies:
1
npm install [email protected]
Copied!
Step 4: Download ready script file and learn API Command to manage loyalty token with your ERP or CRM System:
e.g. node Token_Transfer.js RPC_IP RPC_Port from_address to_address amount contract_address private_key decimals
Execute XRC20 Transfer:
1
node Token_Transfer.js testnet.xinfin.network 443 xdcD000ea0B094EB93Bf4a545994048e630DFef922d xdca5b6045297fc6aec660a2769e3bad08acb2098b3 1000 xdc880997e0a6de5671e8fc9e7b5424cd07b51c9ab8 c3d09a56285d70a531128cec7eb5ae905070f17705d2e1d112eaafd7d257f29b 18
Copied!
1
//to execute the script run the following command
2
// node file_name.js wallet_ip port from_address to_address amount contract_address private_key decimals
3
​
4
​
5
//ip and port for the blockchain node to be connected
6
var wallet_ip = process.argv[2];
7
var wallet_port = process.argv[3];
8
//address from which tokens need to be sent
9
var from_address = process.argv[4];
10
//address to which tokens need to be sent
11
var to_address = process.argv[5];
12
//amount of tokens to be sent
13
var sendamount = process.argv[6];
14
//contract address of the ERC20 token
15
var coinAddress = process.argv[7];
16
//private key of the from address
17
var private_key = process.argv[8];
18
//predefined no. of decimals in the contract
19
var tokendecimal = process.argv[9];
20
​
21
//web3 library needed
22
const Web3 = require("xdc3");
23
​
24
//connecting to the web3 provider
25
if (typeof web3 !== "undefined") {
26
web3 = new Web3(web3.currentProvider);
27
} else {
28
web3 = new Web3(
29
new Web3.providers.HttpProvider("http://" + wallet_ip + ":" + wallet_port)
30
);
31
}
32
​
33
//if the token decimal isn't specified then set it to default 18 and converting the amount to decimal form
34
if (tokendecimal == 18 || tokendecimal == null) {
35
var send_amount = web3.utils.toWei(sendamount);
36
} else {
37
var send_amount = sendamount * Math.pow(10, tokendecimal);
38
}
39
​
40
//data required for estimating the gas that will be needed for the transaction to complete
41
var est_main_gas = { from: from_address, to: to_address, value: send_amount };
42
​
43
//standard ERC20 contract ABI
44
const coinabi = [
45
{
46
constant: true,
47
inputs: [],
48
name: "name",
49
outputs: [{ name: "", type: "string" }],
50
payable: false,
51
stateMutability: "view",
52
type: "function"
53
},
54
{
55
constant: false,
56
inputs: [
57
{ name: "_spender", type: "address" },
58
{ name: "_value", type: "uint256" }
59
],
60
name: "approve",
61
outputs: [{ name: "success", type: "bool" }],
62
payable: false,
63
stateMutability: "nonpayable",
64
type: "function"
65
},
66
{
67
constant: true,
68
inputs: [],
69
name: "totalSupply",
70
outputs: [{ name: "", type: "uint256" }],
71
payable: false,
72
stateMutability: "view",
73
type: "function"
74
},
75
{
76
constant: false,
77
inputs: [
78
{ name: "_from", type: "address" },
79
{ name: "_to", type: "address" },
80
{ name: "_value", type: "uint256" }
81
],
82
name: "transferFrom",
83
outputs: [{ name: "success", type: "bool" }],
84
payable: false,
85
stateMutability: "nonpayable",
86
type: "function"
87
},
88
{
89
constant: true,
90
inputs: [],
91
name: "decimals",
92
outputs: [{ name: "", type: "uint256" }],
93
payable: false,
94
stateMutability: "view",
95
type: "function"
96
},
97
{
98
constant: true,
99
inputs: [{ name: "_owner", type: "address" }],
100
name: "balanceOf",
101
outputs: [{ name: "balance", type: "uint256" }],
102
payable: false,
103
stateMutability: "view",
104
type: "function"
105
},
106
{
107
constant: true,
108
inputs: [],
109
name: "owner",
110
outputs: [{ name: "", type: "address" }],
111
payable: false,
112
stateMutability: "view",
113
type: "function"
114
},
115
{
116
constant: true,
117
inputs: [],
118
name: "symbol",
119
outputs: [{ name: "", type: "string" }],
120
payable: false,
121
stateMutability: "view",
122
type: "function"
123
},
124
{
125
constant: false,
126
inputs: [
127
{ name: "_to", type: "address" },
128
{ name: "_value", type: "uint256" }
129
],
130
name: "transfer",
131
outputs: [{ name: "success", type: "bool" }],
132
payable: false,
133
stateMutability: "nonpayable",
134
type: "function"
135
},
136
{
137
constant: true,
138
inputs: [
139
{ name: "_owner", type: "address" },
140
{ name: "_spender", type: "address" }
141
],
142
name: "allowance",
143
outputs: [{ name: "remaining", type: "uint256" }],
144
payable: false,
145
stateMutability: "view",
146
type: "function"
147
},
148
{
149
constant: false,
150
inputs: [{ name: "_newOwner", type: "address" }],
151
name: "transferOwnership",
152
outputs: [],
153
payable: false,
154
stateMutability: "nonpayable",
155
type: "function"
156
},
157
{
158
inputs: [],
159
payable: false,
160
stateMutability: "nonpayable",
161
type: "constructor"
162
},
163
{
164
anonymous: false,
165
inputs: [
166
{ indexed: true, name: "from", type: "address" },
167
{ indexed: true, name: "to", type: "address" },
168
{ indexed: false, name: "value", type: "uint256" }
169
],
170
name: "Transfer",
171
type: "event"
172
},
173
{
174
anonymous: false,
175
inputs: [
176
{ indexed: true, name: "owner", type: "address" },
177
{ indexed: true, name: "spender", type: "address" },
178
{ indexed: false, name: "value", type: "uint256" }
179
],
180
name: "Approval",
181
type: "event"
182
}
183
];
184
​
185
//creating an instance of the ERC20 contract
186
const coin = new web3.eth.Contract(coinabi, coinAddress);
187
//checking the balance of the from address to asure that it has sufficient balance to complete the transaction
188
coin.methods.balanceOf(from_address).call(function(err, bal) {
189
bal = web3.utils.fromWei(bal, "wei").toString(10);
190
​
191
//generating the data for the transfer method of the ERC20 contract
192
const txdata = coin.methods.transfer(to_address, send_amount).encodeABI(); //to address
193
​
194
//estimating the gas required for the transaction to be completed
195
web3.eth.estimateGas(est_main_gas, function(gaslimit_err, gaslimit) {
196
//getting the current gas price on the network or else setting it to minimum 4 Gwei so that it won't take much time to execute
197
web3.eth.getGasPrice(function(gas_err, getGasPrice) {
198
if (gas_err) {
199
console.log(JSON.stringify({ error1: gas_err }));
200
​
201
getGasPrice = 4000000000;
202
} else {
203
if (getGasPrice < 4000000000 || getGasPrice == null) {
204
getGasPrice = 4000000000;
205
}
206
}
207
​
208
//finding the nonce for the from address
209
web3.eth.getTransactionCount(from_address, function(
210
tx_count_err,
211
transactionCount
212
) {
213
if (tx_count_err) {
214
console.log(
215
JSON.stringify({ "transaction count error ": tx_count_err })
216
);
217
}
218
​
219
//generating the transaction data
220
const trans_det = {
221
nonce: transactionCount, // Replace by nonce for your account on geth node
222
gasPrice: getGasPrice,
223
gas: "200000",
224
to: coinAddress, //contract address
225
from: from_address, //coin base
226
data: txdata
227
};
228
​
229
//signing the transaction generated to get a raw transaction
230
web3.eth.accounts.signTransaction(trans_det, private_key, function(
231
sign_error,
232
signedTransaction
233
) {
234
if (sign_error) {
235
console.log(
236
JSON.stringify({ "sign transaction error ": sign_error })
237
);
238
}
239
​
240
//raw transaction to be sent to the network.
241
const rawTransaction = signedTransaction.rawTransaction;
242
//sending the raw transaction after converting it in to hex format
243
web3.eth.sendSignedTransaction(
244
rawTransaction.toString("hex"),
245
function(trans_err, txid) {
246
//printing the transaction hash or error
247
if (trans_err)
248
console.log(JSON.stringify({ "transaction error": trans_err }));
249
​
250
if (txid && txid != "")
251
console.log(JSON.stringify({ tx: txid, hash: txid }));
252
}
253
);
254
});
255
});
256
});
257
});
258
});
Copied!

Other Useful Command

eth.estimateGas: Executes a transaction or a message call and returns the amount of gas used.
web3.eth.estimateGas(callObject [, callback])
eth.getGasPrice: Returns the current gas price oracle. The gas price is determined by the median of the gas price for the last few blocks.
web3.eth.getGasPrice([callback])
eth.getTransactionCount: Returns the number of transactions sent from an address.
web3.eth.getTransactionCount(address [, defaultBlock] [, callback])
eth.accounts.signTransaction: Signs an Ethereum transaction with a given private key.
web3.eth.accounts.signTransaction(tx, privateKey [, callback]);
eth.sendSignedTransaction: Sends an already signed transaction.
web3.eth.sendSignedTransaction(signedTransactionData [, callback])
For public discussions on the technical issues, join the following public chats or groups:
​Slack Public Chat​
​Telegram​
​Forum​