Wip VM. Created contracts

This commit is contained in:
obscuren 2014-01-03 00:43:49 +01:00
parent 9df4c74511
commit 7cd41ac45a
6 changed files with 80 additions and 18 deletions

View File

@ -4,6 +4,7 @@ import (
_"fmt" _"fmt"
"time" "time"
_"bytes" _"bytes"
_"encoding/hex"
) )
type Block struct { type Block struct {
@ -63,13 +64,36 @@ func CreateBlock(root string, num int, prevHash string, base string, difficulty
extra: extra, extra: extra,
} }
block.state = NewTrie(Db, root) block.state = NewTrie(Db, root)
for _, tx := range txes { 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 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() { func (block *Block) Update() {
} }

View File

@ -45,13 +45,11 @@ func (bm *BlockManager) ProcessBlock(block *Block) error {
} }
func (bm *BlockManager) ProcessTransaction(tx *Transaction, block *Block, lockChan chan bool) { func (bm *BlockManager) ProcessTransaction(tx *Transaction, block *Block, lockChan chan bool) {
if tx.recipient == "\x00" { bm.vm.RunTransaction(tx, block, func(opType OpType) bool {
bm.vm.RunTransaction(tx, block, func(opType OpType) bool { // TODO calculate fees
// TODO calculate fees
return true // Continue return true // Continue
}) })
}
// Broadcast we're done // Broadcast we're done
lockChan <- true lockChan <- true

40
contract.go Normal file
View File

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

View File

@ -3,8 +3,8 @@ package main
import ( import (
"math/big" "math/big"
"fmt" "fmt"
"encoding/hex" _"encoding/hex"
"crypto/sha256" _"crypto/sha256"
_ "bytes" _ "bytes"
) )
@ -63,13 +63,14 @@ func NewTransaction(to string, value uint32, data []string) *Transaction {
tx.data[i] = instr tx.data[i] = instr
} }
b:= []byte(tx.MarshalRlp())
hash := sha256.Sum256(b)
tx.addr = hex.EncodeToString(hash[0:19])
return &tx return &tx
} }
func (tx *Transaction) Hash() []byte {
return Sha256Bin(tx.MarshalRlp())
}
func (tx *Transaction) MarshalRlp() []byte { func (tx *Transaction) MarshalRlp() []byte {
// Prepare the transaction for serialization // Prepare the transaction for serialization
preEnc := []interface{}{ preEnc := []interface{}{

View File

@ -48,7 +48,7 @@ type Trie struct {
} }
func NewTrie(db Database, root string) *Trie { func NewTrie(db Database, root string) *Trie {
return &Trie{db: db, root: ""} return &Trie{db: db, root: root}
} }
/* /*

View File

@ -3,7 +3,6 @@ package main
import ( import (
"fmt" "fmt"
"testing" "testing"
_"encoding/hex"
) )
@ -11,7 +10,7 @@ func TestVm(t *testing.T) {
db, _ := NewMemDatabase() db, _ := NewMemDatabase()
Db = db Db = db
tx := NewTransaction("\x00", 20, []string{ tx := NewTransaction("", 20, []string{
"PSH 10", "PSH 10",
}) })
@ -20,8 +19,8 @@ func TestVm(t *testing.T) {
bm := NewBlockManager() bm := NewBlockManager()
bm.ProcessBlock( block ) bm.ProcessBlock( block )
tx1 := &Transaction{} contract := block.GetContract(tx.Hash())
tx1.UnmarshalRlp([]byte(block.state.Get(tx.recipient))) fmt.Println(contract)
fmt.Println(tx1) fmt.Println("it is", contract.state.Get(string(Encode(0))))
} }