mirror of https://github.com/status-im/nim-abc.git
Transactions
This commit is contained in:
parent
2fbf826655
commit
5661469aee
|
@ -6,4 +6,5 @@ license = "MIT"
|
||||||
requires "questionable >= 0.10.0 & < 0.11.0"
|
requires "questionable >= 0.10.0 & < 0.11.0"
|
||||||
requires "https://github.com/markspanbroek/nim-blscurve#fix-nimble"
|
requires "https://github.com/markspanbroek/nim-blscurve#fix-nimble"
|
||||||
requires "nimcrypto"
|
requires "nimcrypto"
|
||||||
|
requires "stint"
|
||||||
requires "stew"
|
requires "stew"
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import pkg/nimcrypto
|
||||||
|
import pkg/stint
|
||||||
|
import ./keys
|
||||||
|
|
||||||
|
export stint
|
||||||
|
export keys
|
||||||
|
|
||||||
|
type
|
||||||
|
Transaction* = object
|
||||||
|
inputs: seq[TxInput]
|
||||||
|
outputs: seq[TxOutput]
|
||||||
|
signature: Signature
|
||||||
|
TxInput* = tuple
|
||||||
|
txHash: TxHash
|
||||||
|
owner: PublicKey
|
||||||
|
TxOutput* = tuple
|
||||||
|
owner: PublicKey
|
||||||
|
amount: UInt256
|
||||||
|
TxHash* = distinct MDigest[256]
|
||||||
|
|
||||||
|
func `==`*(a, b: TxHash): bool {.borrow.}
|
||||||
|
|
||||||
|
func init*(_: type Transaction,
|
||||||
|
inputs: openArray[TxInput],
|
||||||
|
outputs: openArray[TxOutput]): Transaction =
|
||||||
|
Transaction(inputs: @inputs, outputs: @outputs)
|
||||||
|
|
||||||
|
func init*(_: type Transaction,
|
||||||
|
outputs: openArray[TxOutput]): Transaction =
|
||||||
|
Transaction.init([], outputs)
|
||||||
|
|
||||||
|
func inputs*(transaction: Transaction): seq[TxInput] =
|
||||||
|
transaction.inputs
|
||||||
|
|
||||||
|
func outputs*(transaction: Transaction): seq[TxOutput] =
|
||||||
|
transaction.outputs
|
||||||
|
|
||||||
|
func toBytes*(hash: TxHash): array[32, byte] =
|
||||||
|
MDigest[256](hash).data
|
||||||
|
|
||||||
|
func toBytes*(transaction: Transaction): seq[byte] =
|
||||||
|
result.add(transaction.inputs.len.uint8)
|
||||||
|
for (txHash, owner) in transaction.inputs:
|
||||||
|
result.add(txHash.toBytes)
|
||||||
|
result.add(owner.toBytes)
|
||||||
|
result.add(transaction.outputs.len.uint8)
|
||||||
|
for (owner, amount) in transaction.outputs:
|
||||||
|
result.add(owner.toBytes)
|
||||||
|
result.add(amount.toBytes)
|
||||||
|
|
||||||
|
func hash*(transaction: Transaction): TxHash =
|
||||||
|
TxHash(sha256.digest(transaction.toBytes))
|
|
@ -1,7 +1,13 @@
|
||||||
import abc/keys
|
import abc/keys
|
||||||
|
import abc/transactions
|
||||||
|
|
||||||
proc example*(_: type PrivateKey): PrivateKey =
|
proc example*(_: type PrivateKey): PrivateKey =
|
||||||
PrivateKey.random
|
PrivateKey.random
|
||||||
|
|
||||||
proc example*(_: type PublicKey): PublicKey =
|
proc example*(_: type PublicKey): PublicKey =
|
||||||
PrivateKey.example.toPublicKey
|
PrivateKey.example.toPublicKey
|
||||||
|
|
||||||
|
proc example*(_: type Transaction): Transaction =
|
||||||
|
let alice, bob = PublicKey.example
|
||||||
|
let genesis = Transaction.init({alice: 32.u256, bob: 10.u256})
|
||||||
|
Transaction.init({genesis.hash: alice}, {alice: 2.u256, bob: 30.u256})
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import std/unittest
|
||||||
|
import abc/transactions
|
||||||
|
import ./examples
|
||||||
|
|
||||||
|
suite "Transactions":
|
||||||
|
|
||||||
|
let alice, bob = PublicKey.example
|
||||||
|
|
||||||
|
test "a genesis transaction can be made":
|
||||||
|
let genesis = Transaction.init({alice: 32.u256, bob: 10.u256})
|
||||||
|
|
||||||
|
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":
|
||||||
|
let genesis = Transaction.init({alice: 32.u256, bob: 10.u256})
|
||||||
|
let transaction = Transaction.init(
|
||||||
|
{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":
|
||||||
|
let genesis = Transaction.init({alice: 32.u256, bob: 10.u256})
|
||||||
|
let transaction = Transaction.init(
|
||||||
|
{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
|
Loading…
Reference in New Issue