github.com/igggame/nebulas-go@v2.1.0+incompatible/nebtestkit/cases/contract/contract.lib.crypto.test.js (about) 1 'use strict'; 2 3 var sleep = require('system-sleep'); 4 var FS = require('fs'); 5 var expect = require('chai').expect; 6 var BigNumber = require('bignumber.js'); 7 var HttpRequest = require('../../node-request'); 8 var TestnetConfig = require('../testnet_config'); 9 var Wallet = require('nebulas'); 10 11 var Account = Wallet.Account; 12 var Transaction = Wallet.Transaction; 13 var env = process.argv.splice(2)[1]; 14 var testnetConfig = new TestnetConfig(env); 15 var originSource = testnetConfig.sourceAccount; 16 var ChainID = testnetConfig.ChainId; 17 var coinbase = testnetConfig.coinbase; 18 var neb = new Wallet.Neb(); 19 neb.setRequest(new HttpRequest(testnetConfig.apiEndPoint)); 20 21 22 var deploy, from, contractAddr, source, fromState, coinState; 23 var caseIndex = 0, lastnonce = 0; 24 25 function prepareSource(done) { 26 console.log("originSource address: " + originSource.getAddressString()); 27 neb.api.getAccountState(originSource.getAddressString()).then(function (resp) { 28 console.log("prepare source account state:" + JSON.stringify(resp)); 29 var nonce = parseInt(resp.nonce); 30 31 source = Account.NewAccount(); 32 33 var tx = new Transaction(ChainID, originSource, source, neb.nasToBasic(1000), nonce + 1, "1000000", "200000"); 34 tx.signTransaction(); 35 36 console.log("cliam source tx:", tx.toString()); 37 38 return neb.api.sendRawTransaction(tx.toProtoString()); 39 }).then(function (resp) { 40 console.log("send Raw Tx:" + JSON.stringify(resp)); 41 expect(resp).to.be.have.property('txhash'); 42 checkTransaction(resp.txhash, 0, function (receipt) { 43 console.log("tx receipt : " + JSON.stringify(receipt)); 44 expect(receipt).to.be.have.property('status').equal(1); 45 46 done(); 47 }); 48 }).catch(function (err) { 49 done(err); 50 }); 51 } 52 53 function cliamTokens(accounts, values, done) { 54 for (var i = 0; i < accounts.length; i++) { 55 console.log("acc:"+accounts[i].getAddressString()+" value:"+values[i]); 56 sendTransaction(source, accounts[i], values[i], ++lastnonce); 57 sleep(30); 58 } 59 checkCliamTokens(done); 60 } 61 62 63 function sendTransaction(from, address, value, nonce) { 64 var transaction = new Transaction(ChainID, from, address, value, nonce, "1000000", "200000"); 65 transaction.signTransaction(); 66 var rawTx = transaction.toProtoString(); 67 neb.api.sendRawTransaction(rawTx).then(function (resp) { 68 console.log("send raw transaction resp:" + JSON.stringify(resp)); 69 }); 70 } 71 72 function checkCliamTokens(done) { 73 var intervalAccount = setInterval(function () { 74 neb.api.getAccountState(source.getAddressString()).then(function (resp) { 75 // console.log("master accountState resp:" + JSON.stringify(resp)); 76 var nonce = parseInt(resp.nonce); 77 console.log("check cliam tokens nonce:", lastnonce); 78 79 if (lastnonce <= nonce){ 80 console.log("cliam tokens success"); 81 clearInterval(intervalAccount); 82 done(); 83 } 84 }); 85 }, 2000); 86 } 87 88 function checkTransaction(txhash, retry, done){ 89 90 var maxRetry = 45; 91 92 // contract status and get contract_address 93 var interval = setTimeout(function () { 94 neb.api.getTransactionReceipt(txhash).then(function (resp) { 95 retry++; 96 97 console.log("check transaction status:" + resp.status); 98 if(resp.status && resp.status === 1) { 99 // clearInterval(interval); 100 101 if (resp.contract_address) { 102 console.log("deploy private key:" + deploy.getPrivateKeyString()); 103 console.log("deploy address:" + deploy.getAddressString()); 104 console.log("deploy contract address:" + resp.contract_address); 105 106 contractAddr = resp.contract_address; 107 } 108 109 done(resp); 110 } else if (resp.status && resp.status === 2) { 111 if (retry > maxRetry) { 112 console.log("check transaction time out"); 113 // clearInterval(interval); 114 done(resp); 115 } else { 116 checkTransaction(txhash, retry++, done); 117 } 118 } else { 119 // clearInterval(interval); 120 console.log("transaction execution failed"); 121 done(resp); 122 } 123 }).catch(function (err) { 124 retry++; 125 console.log("check transaction not found retry " + retry); 126 if (retry > maxRetry) { 127 console.log(JSON.stringify(err.error)); 128 // clearInterval(interval); 129 done(err); 130 } else { 131 checkTransaction(txhash, retry++, done); 132 } 133 }); 134 135 }, 2000); 136 } 137 138 139 function deployContract(done, caseGroup) { 140 console.log("start deploying contract: " + caseGroup.groupname); 141 142 neb.api.getAccountState(source.getAddressString()).then(function (resp) { 143 console.log("source account state:" + JSON.stringify(resp)); 144 145 var accounts = new Array(); 146 var values = new Array(); 147 deploy = Account.NewAccount(); 148 accounts.push(deploy); 149 values.push(neb.nasToBasic(1)); 150 151 from = Account.NewAccount(); 152 accounts.push(from); 153 var fromBalance = (typeof caseGroup.fromBalance === "undefined") ? neb.nasToBasic(1) : caseGroup.fromBalance; 154 values.push(fromBalance); 155 156 cliamTokens(accounts, values, () => { 157 try { 158 var source = FS.readFileSync("../../../nf/nvm/test/" + caseGroup.filename, "utf-8"); 159 var contract = { 160 "source": source, 161 "sourceType": caseGroup.type, 162 "args": "" 163 }; 164 165 var tx = new Transaction(testnetConfig.ChainId, deploy, deploy, "0", 1, "10000000", "2000000", contract); 166 tx.signTransaction(); 167 var rawTx = tx.toProtoString(); 168 169 // console.log("contract:" + rawTx); 170 neb.api.sendRawTransaction(rawTx).then(function (resp) { 171 console.log("deploy contract " + caseGroup.groupname + " return: " + JSON.stringify(resp)); 172 173 checkTransaction(resp.txhash, 0, (ret) => { 174 if (ret.status && ret.status === 1) { 175 done(); 176 } else { 177 done(ret); 178 } 179 }); 180 }); 181 } catch (err) { 182 done(err); 183 }; 184 }); 185 186 }).catch (err => done(err)); 187 } 188 189 function runTest(testInput, testExpect, done) { 190 var fromAcc = (typeof testInput.from === "undefined") ? from : testInput.from; 191 var to = (typeof testInput.to === "undefined") ? Account.fromAddress(contractAddr) : testInput.to; 192 193 var fromBalanceBefore, toBalanceBefore; 194 195 neb.api.getAccountState(to.getAddressString()).then(function (resp) { 196 console.log("contractAddr state before: " + JSON.stringify(resp)); 197 toBalanceBefore = resp.balance; 198 return neb.api.getAccountState(from.getAddressString()); 199 }).then(resp => { 200 fromState = resp; 201 fromBalanceBefore = resp.balanece; 202 console.log("from state before: ", JSON.stringify(resp)); 203 return neb.api.getAccountState(coinbase); 204 }).then(function (resp) { 205 console.log("coin state before: ", JSON.stringify(resp)); 206 coinState = resp; 207 208 var tx = new Transaction(ChainID, fromAcc, to, testInput.value, parseInt(fromState.nonce) + testInput.nonce, testInput.gasPrice, testInput.gasLimit, testInput.contract); 209 tx.from.address = fromAcc.address; 210 tx.to.address = to.address; 211 tx.gasPrice = new BigNumber(testInput.gasPrice); 212 tx.gasLimit = new BigNumber(testInput.gasLimit); 213 tx.signTransaction(); 214 console.log("binary tx raw before send: ", tx.toString()); 215 return neb.api.sendRawTransaction(tx.toProtoString()); 216 }).then(function (rawResp) { 217 console.log("send Raw Tx return:" + JSON.stringify(rawResp)); 218 expect(rawResp).to.be.have.property('txhash'); 219 220 checkTransaction(rawResp.txhash, 0, function (receipt) { 221 console.log("tx receipt : " + JSON.stringify(receipt)); 222 try { 223 expect(receipt).to.not.be.a('undefined'); 224 if (true === testExpect.canExcuteTx) { 225 expect(receipt).to.be.have.property('status').equal(1); 226 } else { 227 expect(receipt).to.be.have.property('status').equal(0); 228 } 229 230 neb.api.getAccountState(receipt.from).then(function (state) { 231 232 console.log("from state after: " + JSON.stringify(state)); 233 // expect(state.balance).to.equal(testExpect.fromBalanceAfterTx); 234 return neb.api.getAccountState(contractAddr); 235 }).then(function (state) { 236 237 console.log("contractAddr state after: " + JSON.stringify(state)); 238 var change = new BigNumber(state.balance).minus(new BigNumber(toBalanceBefore)); 239 // expect(change.toString()).to.equal(testExpect.toBalanceChange); 240 return neb.api.getAccountState(coinbase); 241 }).then(function (state) { 242 243 console.log("get coinbase account state before tx:" + JSON.stringify(coinState)); 244 console.log("get coinbase account state after tx:" + JSON.stringify(state)); 245 var reward = new BigNumber(state.balance).sub(coinState.balance); 246 reward = reward.mod(new BigNumber(1.42694).mul(new BigNumber(10).pow(18))); 247 // The transaction should be only 248 // expect(reward.toString()).to.equal(testExpect.transferReward); 249 console.log("coinbase reward: " + reward.toString()); 250 if (receipt.gasUsed) { 251 var txCost = new BigNumber(receipt.gasUsed).mul(receipt.gasPrice).toString(10); 252 // expect(txCost).to.equal(testExpect.transferReward); 253 console.log("tx cost gas: " + txCost.toString()); 254 } 255 256 return neb.api.getEventsByHash(receipt.hash); 257 }).then(function (events) { 258 for (var i = 0; i < events.events.length; i++) { 259 var event = events.events[i]; 260 //console.log("tx event:", JSON.stringify(event,null,'\t')); 261 console.log("tx event data:", event.data); 262 if (event.topic === "chain.transactionResult") { 263 var result = JSON.parse(event.data); 264 expect(result.status).to.equal(testExpect.status); 265 266 if (testExpect.hasOwnProperty("eventErr")){ 267 console.log("Event error checked."); 268 expect(result.error).to.equal(testExpect.eventErr); 269 } 270 271 if (testExpect.hasOwnProperty("result")){ 272 console.log("Result checked."); 273 expect(result.execute_result).to.equal(testExpect.result); 274 } 275 } 276 } 277 done(); 278 }).catch(function (err) { 279 console.log("exe tx err:", err); 280 done(err); 281 }); 282 } catch (err) { 283 console.log("submit tx err:", err.message); 284 done(err); 285 } 286 }); 287 }).catch(function (err) { 288 if (err.error && err.error.error && testExpect.eventErr) { 289 try { 290 expect(err.error.error).to.equal(testExpect.eventErr) 291 done(); 292 } catch (err) { 293 done(err); 294 } 295 return; 296 } 297 done(err); 298 }); 299 } 300 301 var testCaseGroups = []; 302 var caseGroup = { 303 "filename": "contract_crypto.js", 304 "type": "js", 305 "groupname": "case group 0", 306 "groupIndex": 0, 307 308 cases: [ 309 { 310 "name": "0-1. test sha256", 311 "testInput": { 312 value: "0", 313 nonce: 1, 314 gasPrice: 1000000, 315 gasLimit: 2000000, 316 contract: { 317 function: "testSha256", 318 args: "[\"Nebulas is a next generation public blockchain, aiming for a continuously improving ecosystem.\"]" 319 } 320 }, 321 "testExpect": { 322 canExcuteTx: true, 323 toBalanceChange: "0", 324 status: 1, 325 // eventErr: "Call: Error: input seed must be a string", 326 result: "\"a32d6d686968192663b9c9e21e6a3ba1ba9b2e288470c2f98b790256530933e0\"" 327 } 328 }, 329 { 330 "name": "0-2. test sha3256", 331 "testInput": { 332 value: "0", 333 nonce: 1, 334 gasPrice: 1000000, 335 gasLimit: 2000000, 336 contract: { 337 function: "testSha3256", 338 args: "[\"Nebulas is a next generation public blockchain, aiming for a continuously improving ecosystem.\"]" 339 } 340 }, 341 "testExpect": { 342 canExcuteTx: true, 343 toBalanceChange: "0", 344 status: 1, 345 result: "\"564733f9f3e139b925cfb1e7e50ba8581e9107b13e4213f2e4708d9c284be75b\"" 346 } 347 }, 348 { 349 "name": "0-3. test ripemd160", 350 "testInput": { 351 value: "0", 352 nonce: 1, 353 gasPrice: 1000000, 354 gasLimit: 2000000, 355 contract: { 356 function: "testRipemd160", 357 args: "[\"Nebulas is a next generation public blockchain, aiming for a continuously improving ecosystem.\"]" 358 } 359 }, 360 "testExpect": { 361 canExcuteTx: true, 362 toBalanceChange: "0", 363 status: 1, 364 result: "\"4236aa9974eb7b9ddb0f7a7ed06d4bf3d9c0e386\"" 365 } 366 }, 367 { 368 "name": "0-4. test recoverAddress", 369 "testInput": { 370 value: "0", 371 nonce: 1, 372 gasPrice: 1000000, 373 gasLimit: 2000000, 374 contract: { 375 function: "testRecoverAddress", 376 args: "[1,\"564733f9f3e139b925cfb1e7e50ba8581e9107b13e4213f2e4708d9c284be75b\",\"d80e282d165f8c05d8581133df7af3c7c41d51ec7cd8470c18b84a31b9af6a9d1da876ab28a88b0226707744679d4e180691aca6bdef5827622396751a0670c101\"]" 377 } 378 }, 379 "testExpect": { 380 canExcuteTx: true, 381 toBalanceChange: "0", 382 status: 1, 383 result: "\"n1F8QbdnhqpPXDPFT2c9a581tpia8iuF7o2\"" 384 } 385 }, 386 { 387 "name": "0-5. test recoverAddress invalid alg", 388 "testInput": { 389 value: "0", 390 nonce: 1, 391 gasPrice: 1000000, 392 gasLimit: 2000000, 393 contract: { 394 function: "testRecoverAddress", 395 args: "[10,\"564733f9f3e139b925cfb1e7e50ba8581e9107b13e4213f2e4708d9c284be75b\",\"d80e282d165f8c05d8581133df7af3c7c41d51ec7cd8470c18b84a31b9af6a9d1da876ab28a88b0226707744679d4e180691aca6bdef5827622396751a0670c101\"]" 396 } 397 }, 398 "testExpect": { 399 canExcuteTx: true, 400 toBalanceChange: "0", 401 status: 1, 402 result: "null" 403 } 404 }, 405 { 406 "name": "0-6. test md5", 407 "testInput": { 408 value: "0", 409 nonce: 1, 410 gasPrice: 1000000, 411 gasLimit: 2000000, 412 contract: { 413 function: "testMd5", 414 args: "[\"Nebulas is a next generation public blockchain, aiming for a continuously improving ecosystem.\"]" 415 } 416 }, 417 "testExpect": { 418 canExcuteTx: true, 419 toBalanceChange: "0", 420 status: 1, 421 result: "\"9954125a33a380c3117269cff93f76a7\"" 422 } 423 }, 424 { 425 "name": "0-7. test base64", 426 "testInput": { 427 value: "0", 428 nonce: 1, 429 gasPrice: 1000000, 430 gasLimit: 2000000, 431 contract: { 432 function: "testBase64", 433 args: "[\"https://y.qq.com/portal/player_radio.html#id=99\"]" 434 } 435 }, 436 "testExpect": { 437 canExcuteTx: true, 438 toBalanceChange: "0", 439 status: 1, 440 result: "\"aHR0cHM6Ly95LnFxLmNvbS9wb3J0YWwvcGxheWVyX3JhZGlvLmh0bWwjaWQ9OTk=\"" 441 } 442 } 443 ] 444 }; 445 testCaseGroups.push(caseGroup); 446 447 describe('Contract crypto test', () => { 448 449 before(done => prepareSource(done)); 450 451 for (var i = 0; i < testCaseGroups.length; i++) { 452 453 // if (i != 3) {continue;} // selectively run tests 454 455 let caseGroup = testCaseGroups[i]; 456 describe(caseGroup.groupname, () => { 457 before(done => { 458 deployContract(done, caseGroup); 459 caseIndex = 0; 460 }); 461 462 463 for (var j = 0; j < caseGroup.cases.length; j++) { 464 let testCase = caseGroup.cases[j]; 465 it(testCase.name, done => { 466 console.log("===> running case: " + JSON.stringify(testCase)); 467 runTest(testCase.testInput, testCase.testExpect, done); 468 }); 469 } 470 471 afterEach(() => { 472 caseIndex++; 473 console.log("case group: " + caseGroup.groupIndex + ", index: " + caseIndex); 474 }); 475 }); 476 } 477 });