github.com/igggame/nebulas-go@v2.1.0+incompatible/nebtestkit/cases/contract/contract.nrc20.mult.event.test.js (about) 1 'use strict'; 2 var async = require('async'); 3 var sleep = require("system-sleep"); 4 var HttpRequest = require("../../node-request"); 5 var TestNetConfig = require("../testnet_config.js"); 6 7 var FS = require("fs"); 8 9 var expect = require('chai').expect; 10 var BigNumber = require('bignumber.js'); 11 12 var Nebulas = require('nebulas'); 13 var Neb = Nebulas.Neb; 14 var Account = Nebulas.Account; 15 var Transaction = Nebulas.Transaction; 16 var CryptoUtils = Nebulas.CryptoUtils; 17 var Utils = Nebulas.Utils; 18 19 20 var coinbase, coinState; 21 var testCases = new Array(); 22 var caseIndex = 0; 23 24 // mocha cases/contract/contract.nrc20.mult.event.test.js testneb2 -t 200000 25 var args = process.argv.splice(2); 26 var env = args[1]; 27 var testNetConfig = new TestNetConfig(env); 28 29 30 var neb = new Neb(); 31 var source, deploy, from, fromState, contractAddr; 32 var ChainID = testNetConfig.ChainId; 33 var originSource = testNetConfig.sourceAccount; 34 var coinbase = testNetConfig.coinbase; 35 var apiEndPoint = testNetConfig.apiEndPoint; 36 neb.setRequest(new HttpRequest(apiEndPoint)); 37 38 39 var lastnonce = 0; 40 41 function prepareSource(done) { 42 neb.api.getAccountState(originSource.getAddressString()).then(function (resp) { 43 console.log("prepare source account state:" + JSON.stringify(resp)); 44 var nonce = parseInt(resp.nonce); 45 46 source = Account.NewAccount(); 47 48 var tx = new Transaction(ChainID, originSource, source, neb.nasToBasic(1000), nonce + 1, "1000000", "200000"); 49 tx.signTransaction(); 50 51 console.log("cliam source tx:", tx.toString()); 52 53 return neb.api.sendRawTransaction(tx.toProtoString()); 54 }).then(function (resp) { 55 console.log("send Raw Tx:" + JSON.stringify(resp)); 56 expect(resp).to.be.have.property('txhash'); 57 checkTransaction(resp.txhash, function (receipt) { 58 console.log("tx receipt : " + JSON.stringify(receipt)); 59 expect(receipt).to.be.have.property('status').equal(1); 60 61 done(); 62 }); 63 }).catch(function (err) { 64 done(err); 65 }); 66 } 67 68 function prepareContractCall(testCase, done) { 69 neb.api.getAccountState(source.getAddressString()).then(function (resp) { 70 console.log("source account state:" + JSON.stringify(resp)); 71 lastnonce = parseInt(resp.nonce); 72 73 var accounts = new Array(); 74 var values = new Array(); 75 if (Utils.isNull(contractAddr)) { 76 deploy = Account.NewAccount(); 77 accounts.push(deploy); 78 values.push(neb.nasToBasic(1)); 79 } 80 81 if (typeof testCase.testInput.from !== "undefined") { 82 accounts.push(testCase.testInput.from); 83 values.push(neb.nasToBasic(1)); 84 } 85 86 if (typeof testCase.testInput.to !== "undefined") { 87 accounts.push(testCase.testInput.to); 88 values.push(neb.nasToBasic(1)); 89 } 90 91 if (accounts.length > 0) { 92 cliamTokens(accounts, values, function () { 93 if (Utils.isNull(contractAddr)) { 94 deployContract(done); 95 } else { 96 done(); 97 } 98 }); 99 } else { 100 done(); 101 } 102 103 }); 104 } 105 106 function cliamTokens(accounts, values, done) { 107 for (var i = 0; i < accounts.length; i++) { 108 // console.log("acc:"+accounts[i].getAddressString()+"value:"+values[i]); 109 sendTransaction(source, accounts[i], values[i], ++lastnonce); 110 sleep(30); 111 } 112 checkCliamTokens(done); 113 } 114 115 function sendTransaction(from, address, value, nonce) { 116 var transaction = new Transaction(ChainID, from, address, value, nonce, "1000000", "2000000"); 117 transaction.signTransaction(); 118 var rawTx = transaction.toProtoString(); 119 // console.log("send transaction:", transaction.toString()); 120 neb.api.sendRawTransaction(rawTx).then(function (resp) { 121 console.log("send raw transaction resp:" + JSON.stringify(resp)); 122 }); 123 } 124 125 function checkCliamTokens(done) { 126 var intervalAccount = setInterval(function () { 127 neb.api.getAccountState(source.getAddressString()).then(function (resp) { 128 // console.log("master accountState resp:" + JSON.stringify(resp)); 129 var nonce = parseInt(resp.nonce); 130 console.log("check cliam tokens nonce:", lastnonce); 131 132 if (lastnonce <= nonce){ 133 console.log("cliam tokens success"); 134 clearInterval(intervalAccount); 135 136 done(); 137 } 138 }); 139 }, 2000); 140 } 141 142 function deployContract(done){ 143 144 // create contract 145 var source = FS.readFileSync("../nf/nvm/test/NRC20MultEvent.js", "utf-8"); 146 var contract = { 147 "source": source, 148 "sourceType": "js", 149 "args": "[\"StandardToken\", \"NRC\", 18, \"1000000000\"]" 150 }; 151 152 var transaction = new Transaction(ChainID, deploy, deploy, "0", 1, "10000000", "2000000", contract); 153 transaction.signTransaction(); 154 var rawTx = transaction.toProtoString(); 155 156 // console.log("contract:" + rawTx); 157 158 neb.api.sendRawTransaction(rawTx).then(function (resp) { 159 console.log("deploy contract:" + JSON.stringify(resp)); 160 161 checkTransaction(resp.txhash, done); 162 }); 163 } 164 165 function checkTransaction(txhash, done){ 166 167 var retry = 0; 168 var maxRetry = 20; 169 170 // contract status and get contract_address 171 var interval = setInterval(function () { 172 // console.log("getTransactionReceipt hash:"+txhash); 173 neb.api.getTransactionReceipt(txhash).then(function (resp) { 174 retry++; 175 176 console.log("check transaction status:" + resp.status); 177 178 if(resp.status && resp.status === 1) { 179 clearInterval(interval); 180 181 if (resp.contract_address) { 182 console.log("deploy private key:" + deploy.getPrivateKeyString()); 183 console.log("deploy address:" + deploy.getAddressString()); 184 console.log("deploy contract address:" + resp.contract_address); 185 // console.log("deploy receipt:" + JSON.stringify(resp)); 186 187 contractAddr = resp.contract_address; 188 189 // checkNRCBalance(resp.from, resp.contract_address); 190 } 191 192 done(resp); 193 } else if (resp.status && resp.status === 2) { 194 if (retry > maxRetry) { 195 console.log("check transaction time out"); 196 clearInterval(interval); 197 done(resp); 198 } 199 } else { 200 clearInterval(interval); 201 console.log("transaction execution failed"); 202 done(resp); 203 } 204 }).catch(function (err) { 205 retry++; 206 console.log("check transaction not found retry"); 207 if (retry > maxRetry) { 208 console.log(JSON.stringify(err.error)); 209 clearInterval(interval); 210 done(err); 211 } 212 }); 213 214 }, 2000); 215 } 216 217 218 function testTransferByAsync(testInput, testExpect, done) { 219 var from = (Utils.isNull(testInput.from)) ? deploy : testInput.from; 220 var to = Account.NewAccount(); 221 var fromBalance, toBalance; 222 console.log("testTransferByAsync, fromAddress:%s, toAddress:%s", 223 from.getAddressString(), to.getAddressString()); 224 async.auto({ 225 getFromBalance: function(callback) { 226 var RR = balanceOfNRC20(from.getAddressString()); 227 RR.then(function(resp) { 228 fromBalance = JSON.parse(resp.result); 229 console.log("from balance:", fromBalance); 230 callback(null, fromBalance); 231 }).catch(function(err){ 232 console.log("getFromBalance err:", err); 233 callback(err, null); 234 }) 235 }, 236 getToBalance: function(callback) { 237 var RR = balanceOfNRC20(to.getAddressString()); 238 RR.then(function(resp) { 239 toBalance = JSON.parse(resp.result); 240 console.log("to balance:", toBalance); 241 callback(null, toBalance); 242 }).catch(function(err){ 243 console.log("getToBalance err:", err); 244 callback(err, null); 245 }) 246 247 }, 248 getAccountState: function(callback) { 249 var RR = neb.api.getAccountState(from.getAddressString()); 250 //callback(null, resp); 251 RR.then(function(resp) { 252 console.log("state:", resp); 253 callback(null, resp); 254 }).catch(function(err){ 255 console.log("getAccountState err:", err); 256 callback(err, null); 257 }) 258 }, 259 executeContract: ['getFromBalance', 'getToBalance', 'getAccountState', function(callback, results){ 260 console.log("from state:", JSON.stringify(results.getAccountState)); 261 262 var args = testInput.args; 263 if (!Utils.isNull(testInput.transferValue)) { 264 if (testInput.transferValue === "from.balance") { 265 testInput.transferValue = fromBalance; 266 } 267 args = "[\""+ to.getAddressString() +"\", \""+ testInput.transferValue +"\"]"; 268 } 269 270 var contract = { 271 "function": testInput.function, 272 "args": args 273 }; 274 var tx = new Transaction(ChainID, from, contractAddr, "0", parseInt(results.getAccountState.nonce) + 1, "1000000", "2000000", contract); 275 tx.signTransaction(); 276 277 console.log("raw tx:", tx.toString()); 278 var RR = neb.api.sendRawTransaction(tx.toProtoString()); 279 RR.then(function(resp) { 280 callback(null, resp); 281 }).catch(function(err){ 282 console.log("executeContract err:", err); 283 callback(err, null); 284 }) 285 }], 286 checkContract: ['executeContract', function(callback, newtx){ 287 checkTransaction(newtx.executeContract.txhash, function(resp) { 288 console.log("checkTransaction:", resp); 289 if (resp.status == 0) { 290 //callback("checkTransaction execut contract failed!", null); 291 callback(null, resp); 292 } else { 293 294 expect(resp).to.be.have.property('status').equal(testExpect.status); 295 callback(null, resp); 296 } 297 }); 298 }], 299 getAfterFromBalance: ['checkContract', function(callback, receipt){ 300 var RR = balanceOfNRC20(from.getAddressString()); 301 RR.then(function(resp) { 302 var balance = JSON.parse(resp.result); 303 console.log("after from balance:", balance); 304 if (testExpect.status === 1) { 305 var balanceNumber = new BigNumber(fromBalance).sub(testInput.transferValue); 306 expect(balanceNumber.toString(10)).to.equal(balance); 307 } else { 308 expect(balance).to.equal(fromBalance); 309 } 310 fromBalance = balance; 311 callback(null, balance); 312 }).catch(function(err){ 313 console.log("after getFromBalance err:", err); 314 callback(err, null); 315 }) 316 }], 317 getAfterToBalance: ['checkContract', function(callback, receipt){ 318 var RR = balanceOfNRC20(to.getAddressString()); 319 RR.then(function(resp) { 320 var balance = JSON.parse(resp.result); 321 console.log("after to balance:", balance); 322 if (testExpect.status === 1) { 323 var balanceNumber = new BigNumber(toBalance).plus(testInput.transferValue); 324 expect(balanceNumber.toString(10)).to.equal(balance); 325 } else { 326 expect(toBalance).to.equal(balance); 327 } 328 toBalance = balance; 329 callback(null, balance); 330 }).catch(function(err){ 331 console.log("after getToBalance err:", err); 332 callback(err, null); 333 }) 334 }], 335 getEventsByHash: ['checkContract', function(callback, receipt){ 336 var RR = neb.api.getEventsByHash(receipt.checkContract.hash); 337 RR.then(function(events) { 338 //console.log("events:", events); 339 for (var i = 0; i < events.events.length; i++) { 340 var event = events.events[i]; 341 console.log("tx event:", event); 342 if (event.topic == "chain.transactionResult") { 343 var result = JSON.parse(event.data); 344 expect(result.status).to.equal(testExpect.status); 345 } else { 346 var data = JSON.parse(event.data); 347 if (testExpect.events[i] == null) { 348 expect(typeof(data.Transfer)).equal('undefined'); 349 continue; 350 } 351 //check event value 352 if (testExpect.events[i].from) { 353 expect(data.Transfer.from).to.equal(from.getAddressString()); 354 } else { 355 expect(typeof(data.Transfer.from)).equal('undefined'); 356 } 357 if (testExpect.events[i].to) { 358 expect(data.Transfer.to).to.equal(to.getAddressString()); 359 } else { 360 expect(typeof(data.Transfer.to)).equal('undefined'); 361 } 362 if (testExpect.events[i].value) { 363 expect(data.Transfer.value).to.equal(testInput.transferValue); 364 } else { 365 expect(typeof(data.Transfer.value)).equal('undefined'); 366 } 367 } 368 369 } 370 expect(events.events.length).to.equal(testExpect.events.length + 1); 371 callback(null, events); 372 }).catch(function(err) { 373 console.log("getEventsByHash err"); 374 callback(err, null); 375 }) 376 377 }], 378 }, function(err, results) { 379 if (err) { 380 console.log("async.auto hava break:", err); 381 if (err == "checkTransaction execut contract failed!") { 382 done(); 383 } else { 384 done(err); 385 } 386 } else { 387 console.log("end async.auto"); 388 done(); 389 } 390 }); 391 } 392 393 function balanceOfNRC20(address) { 394 var contract = { 395 "function": "balanceOf", 396 "args": "[\"" + address + "\"]" 397 }; 398 return neb.api.call(address, contractAddr, "0", 1, "1000000", "200000", contract) 399 } 400 401 function allowanceOfNRC20(owner, spender) { 402 var contract = { 403 "function": "allowance", 404 "args": "[\"" + owner + "\", \""+ spender +"\"]" 405 }; 406 return neb.api.call(owner, contractAddr, "0", 1, "1000000", "2000000", contract) 407 } 408 var EventExpect = function(from, to, value) { 409 this.from = from; 410 this.to = to; 411 this.value = value; 412 }; 413 414 var testCase = { 415 "name": "1. transfer mult event", 416 "testInput": { 417 isTransfer: true, 418 transferValue: "1", 419 function: "transferforMultEvent", 420 args: "" 421 }, 422 "testExpect": { 423 status: 1, 424 events: [new EventExpect(1, 1, 1), new EventExpect(1,0,1), new EventExpect(0, 1, 1), new EventExpect(0, 0, 1),], 425 } 426 }; 427 428 testCases.push(testCase); 429 430 testCase = { 431 "name": "2. transfer mult event Status is err", 432 "testInput": { 433 isTransfer: true, 434 function: "transferforMultEventStatus", 435 args: "" 436 }, 437 "testExpect": { 438 status: 0, 439 events: [] 440 } 441 }; 442 testCases.push(testCase); 443 444 testCase = { 445 "name": "3. transfer mult event args has err", 446 "testInput": { 447 isTransfer: true, 448 transferValue: "1", 449 function: "transferforMultEventTransfer", 450 args: "" 451 }, 452 "testExpect": { 453 status: 1, 454 events: [null, new EventExpect(1,1,1),], 455 } 456 }; 457 testCases.push(testCase); 458 459 describe('contract call test', function () { 460 before(function (done) { 461 prepareSource(done); 462 }); 463 464 for (var i = 0; i < testCases.length; i++) { 465 466 it(testCases[i].name, function (done) { 467 var testCase = testCases[caseIndex]; 468 prepareContractCall(testCase, function (err) { 469 if (err instanceof Error) { 470 done(err); 471 } else { 472 testTransferByAsync(testCase.testInput, testCase.testExpect, done); 473 } 474 }); 475 }); 476 } 477 478 afterEach(function () { 479 caseIndex++; 480 }); 481 });