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  });