aboutsummaryrefslogtreecommitdiffstats
path: root/common/natspec/natspec.go
diff options
context:
space:
mode:
authorzsfelfoldi <zsfelfoldi@gmail.com>2015-03-31 14:28:12 +0800
committerzelig <viktor.tron@gmail.com>2015-04-20 03:57:48 +0800
commit3136bae4a5f08820d3116b61b783c100c169717c (patch)
tree9295831c571081061a67dd1d670490924e114c22 /common/natspec/natspec.go
parent97a602864a485bb3a79f460077052bd76cdbff99 (diff)
downloadgo-tangerine-3136bae4a5f08820d3116b61b783c100c169717c.tar.gz
go-tangerine-3136bae4a5f08820d3116b61b783c100c169717c.tar.zst
go-tangerine-3136bae4a5f08820d3116b61b783c100c169717c.zip
NatSpec, URL register storage retrieval
fixed 2/3 tests
Diffstat (limited to 'common/natspec/natspec.go')
-rw-r--r--common/natspec/natspec.go97
1 files changed, 79 insertions, 18 deletions
diff --git a/common/natspec/natspec.go b/common/natspec/natspec.go
index f6b91d03d..883e27ef3 100644
--- a/common/natspec/natspec.go
+++ b/common/natspec/natspec.go
@@ -1,6 +1,7 @@
package natspec
import (
+ "bytes"
"encoding/json"
"fmt"
"github.com/robertkrimen/otto"
@@ -8,32 +9,93 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/xeth"
)
type abi2method map[[8]byte]*method
type NatSpec struct {
jsvm *otto.Otto
- methods abi2method
userDocJson, abiDocJson []byte
userDoc userDoc
+ tx, data string
// abiDoc abiDoc
}
// TODO: should initialise with abi and userdoc jsons
-func New() (self *NatSpec, err error) {
- // fetch abi, userdoc
- abi := []byte("")
- userdoc := []byte("")
- return NewWithDocs(abi, userdoc)
+func New(xeth *xeth.XEth, tx string) (self *NatSpec, err error) {
+
+ // extract contract address from tx
+
+ var obj map[string]json.RawMessage
+ err = json.Unmarshal([]byte(tx), &obj)
+ if err != nil {
+ return
+ }
+ var tmp []map[string]string
+ err = json.Unmarshal(obj["params"], &tmp)
+ if err != nil {
+ return
+ }
+ contractAddress := tmp[0]["to"]
+
+ // retrieve contract hash from state
+ if !xeth.IsContract(contractAddress) {
+ err = fmt.Errorf("NatSpec error: contract not found")
+ return
+ }
+ codeHash := xeth.CodeAt(contractAddress)
+
+ // retrieve natspec info content hash
+
+ statereg := NewStateReg(xeth)
+
+ natspecHash, err1 := statereg.GetNatSpec(codeHash)
+ if err1 != nil {
+ return nil, err1
+ }
+
+ // retrieve content
+
+ content, err2 := statereg.GetContent(natspecHash)
+ if err2 != nil {
+ return nil, err2
+ }
+
+ // get abi, userdoc
+ var obj2 map[string]json.RawMessage
+ err = json.Unmarshal(content, &obj2)
+ if err != nil {
+ return
+ }
+
+ abi := []byte(obj2["abi"])
+ userdoc := []byte(obj2["userdoc"])
+
+ self, err = NewWithDocs(abi, userdoc, tx)
+ return
}
-func NewWithDocs(abiDocJson, userDocJson []byte) (self *NatSpec, err error) {
+func NewWithDocs(abiDocJson, userDocJson []byte, tx string) (self *NatSpec, err error) {
+
+ var obj map[string]json.RawMessage
+ err = json.Unmarshal([]byte(tx), &obj)
+ if err != nil {
+ return
+ }
+ var tmp []map[string]string
+ err = json.Unmarshal(obj["params"], &tmp)
+ if err != nil {
+ return
+ }
+ data := tmp[0]["data"]
self = &NatSpec{
jsvm: otto.New(),
abiDocJson: abiDocJson,
userDocJson: userDocJson,
+ tx: tx,
+ data: data,
}
_, err = self.jsvm.Run(natspecJS)
@@ -74,34 +136,33 @@ type userDoc struct {
}
func (self *NatSpec) makeAbi2method(abiKey [8]byte) (meth *method) {
- if self.methods != nil {
- meth = self.methods[abiKey]
- return
- }
- self.methods = make(abi2method)
for signature, m := range self.userDoc.Methods {
name := strings.Split(signature, "(")[0]
hash := []byte(common.Bytes2Hex(crypto.Sha3([]byte(signature))))
var key [8]byte
copy(key[:], hash[:8])
- self.methods[key] = meth
- meth.name = name
- if key == abiKey {
+ if bytes.Equal(key[:], abiKey[:]) {
meth = m
+ meth.name = name
+ return
}
}
return
}
-func (self *NatSpec) Notice(tx string, abi string) (notice string, err error) {
+func (self *NatSpec) Notice() (notice string, err error) {
var abiKey [8]byte
- copy(abiKey[:], []byte(abi)[:8])
+ if len(self.data) < 10 {
+ err = fmt.Errorf("Invalid transaction data")
+ return
+ }
+ copy(abiKey[:], self.data[2:10])
meth := self.makeAbi2method(abiKey)
if meth == nil {
err = fmt.Errorf("abi key %x does not match any method %v")
return
}
- notice, err = self.noticeForMethod(tx, meth.name, meth.Notice)
+ notice, err = self.noticeForMethod(self.tx, meth.name, meth.Notice)
return
}