2021-06-29 13:24:11 +00:00
|
|
|
import ./basics
|
2021-06-28 13:04:50 +00:00
|
|
|
|
|
|
|
suite "Transactions":
|
|
|
|
|
2021-06-29 09:18:33 +00:00
|
|
|
let aliceKey, bobKey = PrivateKey.example
|
|
|
|
let alice = aliceKey.toPublicKey
|
|
|
|
let bob = bobKey.toPublicKey
|
2021-06-28 13:04:50 +00:00
|
|
|
|
|
|
|
test "a genesis transaction can be made":
|
|
|
|
let genesis = Transaction.init({alice: 32.u256, bob: 10.u256})
|
2021-06-29 09:00:40 +00:00
|
|
|
check genesis.isSome
|
2021-06-28 13:04:50 +00:00
|
|
|
|
|
|
|
test "a transaction has a hash":
|
|
|
|
let transaction1, transaction2 = Transaction.example
|
|
|
|
check transaction1.hash == transaction1.hash
|
|
|
|
check transaction2.hash == transaction2.hash
|
|
|
|
check transaction1.hash != transaction2.hash
|
|
|
|
|
|
|
|
test "a transaction references outputs from other transactions":
|
2021-06-29 09:00:40 +00:00
|
|
|
let genesis = !Transaction.init({alice: 32.u256, bob: 10.u256})
|
|
|
|
let transaction = !Transaction.init(
|
2021-06-28 13:04:50 +00:00
|
|
|
{genesis.hash: alice},
|
|
|
|
{alice: 2.u256, bob: 30.u256}
|
|
|
|
)
|
|
|
|
check transaction.inputs.len == 1
|
|
|
|
check transaction.outputs.len == 2
|
|
|
|
|
|
|
|
test "a transaction can be converted to bytes":
|
2021-06-29 09:00:40 +00:00
|
|
|
let genesis = !Transaction.init({alice: 32.u256, bob: 10.u256})
|
|
|
|
let transaction = !Transaction.init(
|
2021-06-28 13:04:50 +00:00
|
|
|
{genesis.hash: alice},
|
|
|
|
{alice: 2.u256, bob: 30.u256}
|
|
|
|
)
|
|
|
|
var expected: seq[byte]
|
|
|
|
expected.add(1) # amount of inputs
|
|
|
|
expected.add(genesis.hash.toBytes)
|
|
|
|
expected.add(alice.toBytes)
|
|
|
|
expected.add(2) # amount of outputs
|
|
|
|
expected.add(alice.toBytes)
|
|
|
|
expected.add(2.u256.toBytes)
|
|
|
|
expected.add(bob.toBytes)
|
|
|
|
expected.add(30.u256.toBytes)
|
|
|
|
check transaction.toBytes == expected
|
2021-06-28 15:08:05 +00:00
|
|
|
|
|
|
|
test "signatures can be added to a transaction":
|
|
|
|
let key1, key2 = PrivateKey.example
|
|
|
|
var transaction = Transaction.example
|
|
|
|
let sig1 = key1.sign(transaction.hash.toBytes)
|
|
|
|
let sig2 = key2.sign(transaction.hash.toBytes)
|
|
|
|
transaction.add(sig1)
|
|
|
|
check transaction.signature == sig1
|
|
|
|
transaction.add(sig2)
|
|
|
|
check transaction.signature == aggregate(sig1, sig2)
|
2021-06-29 09:00:40 +00:00
|
|
|
|
2021-06-29 13:17:53 +00:00
|
|
|
test "transaction can be signed by a private key":
|
|
|
|
let key = PrivateKey.example
|
|
|
|
var transaction = Transaction.example
|
|
|
|
key.sign(transaction)
|
|
|
|
check transaction.signature == key.sign(transaction.hash.toBytes)
|
|
|
|
|
2021-06-29 09:18:33 +00:00
|
|
|
test "transaction signature can be checked for validity":
|
|
|
|
let genesis = !Transaction.init({alice: 32.u256, bob: 10.u256})
|
|
|
|
check not genesis.hasValidSignature()
|
|
|
|
var transaction = !Transaction.init(
|
|
|
|
{genesis.hash: alice},
|
|
|
|
{alice: 2.u256, bob: 30.u256}
|
|
|
|
)
|
|
|
|
let hash = transaction.hash.toBytes
|
|
|
|
check not transaction.hasValidSignature
|
|
|
|
transaction.add(aliceKey.sign(hash))
|
|
|
|
check transaction.hasValidSignature
|
|
|
|
transaction.add(bobKey.sign(hash))
|
|
|
|
check not transaction.hasValidSignature
|
|
|
|
|
2021-06-29 09:00:40 +00:00
|
|
|
test "transaction must have at least one output":
|
|
|
|
check Transaction.init([]).isNone
|
|
|
|
|
|
|
|
test "multiple outputs to the same owner are not allowed":
|
|
|
|
check Transaction.init({alice: 40.u256, alice: 2.u256}).isNone
|