From 7cd41ac45aed7ee22ef02f8abedf83a2914c4807 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 3 Jan 2014 00:43:49 +0100 Subject: [PATCH] Wip VM. Created contracts --- block.go | 26 +++++++++++++++++++++++++- block_manager.go | 10 ++++------ contract.go | 40 ++++++++++++++++++++++++++++++++++++++++ transaction.go | 11 ++++++----- trie.go | 2 +- vm_test.go | 9 ++++----- 6 files changed, 80 insertions(+), 18 deletions(-) create mode 100644 contract.go diff --git a/block.go b/block.go index 146328471..dd329f8ac 100644 --- a/block.go +++ b/block.go @@ -4,6 +4,7 @@ import ( _"fmt" "time" _"bytes" + _"encoding/hex" ) type Block struct { @@ -63,13 +64,36 @@ func CreateBlock(root string, num int, prevHash string, base string, difficulty extra: extra, } block.state = NewTrie(Db, root) + for _, tx := range txes { - block.state.Update(tx.recipient, string(tx.MarshalRlp())) + // Create contract if there's no recipient + if tx.recipient == "" { + addr := tx.Hash() + + contract := NewContract(tx.value, []byte("")) + block.state.Update(string(addr), string(contract.MarshalRlp())) + for i, val := range tx.data { + contract.state.Update(string(Encode(i)), val) + } + block.UpdateContract(addr, contract) + } } return block } +func (block *Block) GetContract(addr []byte) *Contract { + data := block.state.Get(string(addr)) + contract := &Contract{} + contract.UnmarshalRlp([]byte(data)) + + return contract +} + +func (block *Block) UpdateContract(addr []byte, contract *Contract) { + block.state.Update(string(addr), string(contract.MarshalRlp())) +} + func (block *Block) Update() { } diff --git a/block_manager.go b/block_manager.go index 0ef5d1108..f3aa29ba4 100644 --- a/block_manager.go +++ b/block_manager.go @@ -45,13 +45,11 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { } func (bm *BlockManager) ProcessTransaction(tx *Transaction, block *Block, lockChan chan bool) { - if tx.recipient == "\x00" { - bm.vm.RunTransaction(tx, block, func(opType OpType) bool { - // TODO calculate fees + bm.vm.RunTransaction(tx, block, func(opType OpType) bool { + // TODO calculate fees - return true // Continue - }) - } + return true // Continue + }) // Broadcast we're done lockChan <- true diff --git a/contract.go b/contract.go new file mode 100644 index 000000000..e95e50b74 --- /dev/null +++ b/contract.go @@ -0,0 +1,40 @@ +package main + +import ( +) + +type Contract struct { + active int + amount uint32 // ??? + state *Trie +} +func NewContract(amount uint32, root []byte) *Contract { + contract := &Contract{active: 1, amount: amount} + contract.state = NewTrie(Db, string(root)) + + return contract +} +func (c *Contract) MarshalRlp() []byte { + // Prepare the transaction for serialization + preEnc := []interface{}{uint32(c.active), c.amount, c.state.root} + + return Encode(preEnc) +} + +func (c *Contract) UnmarshalRlp(data []byte) { + t, _ := Decode(data, 0) + + if slice, ok := t.([]interface{}); ok { + if active, ok := slice[0].(uint8); ok { + c.active = int(active) + } + + if amount, ok := slice[1].(uint8); ok { + c.amount = uint32(amount) + } + + if root, ok := slice[2].([]uint8); ok { + c.state = NewTrie(Db, string(root)) + } + } +} diff --git a/transaction.go b/transaction.go index 562593c96..dc5204f9b 100644 --- a/transaction.go +++ b/transaction.go @@ -3,8 +3,8 @@ package main import ( "math/big" "fmt" - "encoding/hex" - "crypto/sha256" + _"encoding/hex" + _"crypto/sha256" _ "bytes" ) @@ -63,13 +63,14 @@ func NewTransaction(to string, value uint32, data []string) *Transaction { tx.data[i] = instr } - b:= []byte(tx.MarshalRlp()) - hash := sha256.Sum256(b) - tx.addr = hex.EncodeToString(hash[0:19]) return &tx } +func (tx *Transaction) Hash() []byte { + return Sha256Bin(tx.MarshalRlp()) +} + func (tx *Transaction) MarshalRlp() []byte { // Prepare the transaction for serialization preEnc := []interface{}{ diff --git a/trie.go b/trie.go index 83a3073ae..442cc08b8 100644 --- a/trie.go +++ b/trie.go @@ -48,7 +48,7 @@ type Trie struct { } func NewTrie(db Database, root string) *Trie { - return &Trie{db: db, root: ""} + return &Trie{db: db, root: root} } /* diff --git a/vm_test.go b/vm_test.go index d0bcda2ca..00b8809a1 100644 --- a/vm_test.go +++ b/vm_test.go @@ -3,7 +3,6 @@ package main import ( "fmt" "testing" - _"encoding/hex" ) @@ -11,7 +10,7 @@ func TestVm(t *testing.T) { db, _ := NewMemDatabase() Db = db - tx := NewTransaction("\x00", 20, []string{ + tx := NewTransaction("", 20, []string{ "PSH 10", }) @@ -20,8 +19,8 @@ func TestVm(t *testing.T) { bm := NewBlockManager() bm.ProcessBlock( block ) - tx1 := &Transaction{} - tx1.UnmarshalRlp([]byte(block.state.Get(tx.recipient))) - fmt.Println(tx1) + contract := block.GetContract(tx.Hash()) + fmt.Println(contract) + fmt.Println("it is", contract.state.Get(string(Encode(0)))) }