public void TestTransactionPushOutput() { var tx = transutils.makeEmptyTransaction(); var a = transutils.makeAddress(); var err = SKY_coin_Transaction_PushOutput(tx, a, 100, 150); Assert.AreEqual(err, SKY_OK); var count = new_Gointp(); err = SKY_coin_Transaction_GetOutputsCount(tx, count); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(Gointp_value(count), 1); var pOut1 = new coin__TransactionOutput(); var pOut = new coin__TransactionOutput(); pOut1.Address = a; pOut1.Coins = 100; pOut1.Hours = 150; err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOut); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(pOut.isEqual(pOut1), 1); for (int i = 1; i < 20; i++) { a = transutils.makeAddress(); err = SKY_coin_Transaction_PushOutput(tx, a, (ulong)(i * 100), (ulong)(i * 50)); Assert.AreEqual(err, SKY_OK); count = new_Gointp(); err = SKY_coin_Transaction_GetOutputsCount(tx, count); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(Gointp_value(count), (i + 1)); pOut1 = new coin__TransactionOutput(); pOut = new coin__TransactionOutput(); pOut1.Address = a; pOut1.Coins = (ulong)(i * 100); pOut1.Hours = (ulong)(i * 50); err = SKY_coin_Transaction_GetOutputAt(tx, i, pOut); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(pOut.isEqual(pOut1), 1); } }
public void TestTransactionHashInner() { var handle = new_Transaction__Handlep(); makeTransaction(handle); var h = new cipher_SHA256(); var err = SKY_coin_Transaction_HashInner(handle, h); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(h.isEqual(new cipher_SHA256()), 0); // If tx.In is changed, hash should change var handle2 = transutils.copyTransaction(handle); Assert.AreEqual(err, SKY_OK); var ux = new coin__UxOut(); makeUxOut(ux); h = new cipher_SHA256(); var h1 = new cipher_SHA256(); err = SKY_coin_UxOut_Hash(ux, h); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_SetInputAt(handle2, 0, h); Assert.AreEqual(err, SKY_OK); err = SKY_coin_UxOut_Hash(ux, h1); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(h.isEqual(h1), 1); err = SKY_coin_Transaction_HashInner(handle, h); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_HashInner(handle2, h1); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(h.isEqual(h1), 0); // If tx.Out is changed, hash should change handle2 = transutils.copyTransaction(handle); var a = transutils.makeAddress(); var pOut = new coin__TransactionOutput(); err = SKY_coin_Transaction_GetOutputAt(handle2, 0, pOut); Assert.AreEqual(err, SKY_OK); pOut.Address = a; err = SKY_coin_Transaction_SetOutputAt(handle2, 0, pOut); Assert.AreEqual(err, SKY_OK); var sha1 = new cipher_SHA256(); var sha2 = new cipher_SHA256(); err = SKY_coin_Transaction_HashInner(handle, sha1); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_HashInner(handle2, sha2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(sha1.isEqual(sha2), 0); // If tx.Head is changed, hash should not change handle2 = transutils.copyTransaction(handle); var sig = new cipher_Sig(); err = SKY_coin_Transaction_PushSignature(handle, sig); Assert.AreEqual(err, SKY_OK); sha1 = new cipher_SHA256(); sha2 = new cipher_SHA256(); err = SKY_coin_Transaction_HashInner(handle, sha1); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_HashInner(handle2, sha2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(sha1.isEqual(sha2), 1); }
public void TestTransactionVerify() { // Mismatch header hash var tx = transutils.makeEmptyTransaction(); var ptx = makeTransaction(tx); ptx.setInnerHash(new cipher_SHA256()); var err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // No inputs tx = new_Transaction__Handlep(); makeTransaction(tx); err = SKY_coin_Transaction_ResetInputs(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // No outputs makeTransaction(tx); err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK, ""); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Invalid number of Sigs makeTransaction(tx); err = SKY_coin_Transaction_ResetSignatures(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); err = SKY_coin_Transaction_ResetSignatures(tx, 20); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Too many sigs & inputs makeTransaction(tx); err = SKY_coin_Transaction_ResetSignatures(tx, short.MaxValue); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_ResetInputs(tx, short.MaxValue); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Duplicate inputs var ux = new coin__UxOut(); var s = new cipher_SecKey(); var h = new cipher_SHA256(); makeUxOutWithSecret(ux, s); makeTransactionFromUxOut(ux, s, tx); err = SKY_coin_Transaction_GetInputAt(tx, 0, h); Assert.AreEqual(err, SKY_OK); var r = new uint(); r = SKY_coin_Transaction_PushInput(tx, h); Assert.AreEqual(r, SKY_OK); err = SKY_coin_Transaction_ResetSignatures(tx, 0); Assert.AreEqual(err, SKY_OK); var secKeys = new cipher_SecKeys(); secKeys.allocate(2); secKeys.setAt(0, s); secKeys.setAt(1, s); err = SKY_coin_Transaction_SignInputs(tx, secKeys); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Duplicate outputs makeTransaction(tx); var pOutput = new coin__TransactionOutput(); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); pOutput.Address = new cipher__Address(); err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Output coins are 0 makeTransaction(tx); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); pOutput.Coins = 0; err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Output coin overflow makeTransaction(tx); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); pOutput.Coins = (ulong)(ulong.MaxValue - 3e6); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Output coins are not multiples of 1e6 (valid, decimal restriction is not enforced here) makeTransaction(tx); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK); pOutput.Coins += 10; err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_ResetSignatures(tx, 0); Assert.AreEqual(err, SKY_OK); var p = new cipher_PubKey(); s = new cipher_SecKey(); err = SKY_cipher_GenerateKeyPair(p, s); Assert.AreEqual(err, SKY_OK); secKeys = new cipher_SecKeys(); secKeys.allocate(1); secKeys.setAt(0, s); err = SKY_coin_Transaction_SignInputs(tx, secKeys); Assert.AreEqual(err, SKY_OK); Assert.IsTrue(pOutput.Coins % 1e6 != 0); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_OK); // Valid makeTransaction(tx); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, (ulong)(10e6), pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, (ulong)(1e6), pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_OK); }