parent
c5e39dfabf
commit
1cf1fe5d74
32 changed files with 320 additions and 304 deletions
|
@ -1,80 +1,50 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
)
|
||||
|
||||
// Contract holds information about a smart contract in the NEO blockchain.
|
||||
type Contract struct {
|
||||
ID int32
|
||||
Script []byte
|
||||
Manifest manifest.Manifest
|
||||
|
||||
scriptHash util.Uint160
|
||||
ID int32 `json:"id"`
|
||||
UpdateCounter uint16 `json:"updatecounter"`
|
||||
Hash util.Uint160 `json:"hash"`
|
||||
Script []byte `json:"script"`
|
||||
Manifest manifest.Manifest `json:"manifest"`
|
||||
}
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (cs *Contract) DecodeBinary(br *io.BinReader) {
|
||||
cs.ID = int32(br.ReadU32LE())
|
||||
cs.UpdateCounter = br.ReadU16LE()
|
||||
cs.Hash.DecodeBinary(br)
|
||||
cs.Script = br.ReadVarBytes()
|
||||
cs.Manifest.DecodeBinary(br)
|
||||
cs.createHash()
|
||||
}
|
||||
|
||||
// EncodeBinary implements Serializable interface.
|
||||
func (cs *Contract) EncodeBinary(bw *io.BinWriter) {
|
||||
bw.WriteU32LE(uint32(cs.ID))
|
||||
bw.WriteU16LE(cs.UpdateCounter)
|
||||
cs.Hash.EncodeBinary(bw)
|
||||
bw.WriteVarBytes(cs.Script)
|
||||
cs.Manifest.EncodeBinary(bw)
|
||||
}
|
||||
|
||||
// ScriptHash returns a contract script hash.
|
||||
func (cs *Contract) ScriptHash() util.Uint160 {
|
||||
if cs.scriptHash.Equals(util.Uint160{}) {
|
||||
cs.createHash()
|
||||
// CreateContractHash creates deployed contract hash from transaction sender
|
||||
// and contract script.
|
||||
func CreateContractHash(sender util.Uint160, script []byte) util.Uint160 {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.Opcodes(w.BinWriter, opcode.ABORT)
|
||||
emit.Bytes(w.BinWriter, sender.BytesBE())
|
||||
emit.Bytes(w.BinWriter, script)
|
||||
if w.Err != nil {
|
||||
panic(w.Err)
|
||||
}
|
||||
return cs.scriptHash
|
||||
}
|
||||
|
||||
// createHash creates contract script hash.
|
||||
func (cs *Contract) createHash() {
|
||||
cs.scriptHash = hash.Hash160(cs.Script)
|
||||
}
|
||||
|
||||
type contractJSON struct {
|
||||
ID int32 `json:"id"`
|
||||
Script []byte `json:"script"`
|
||||
Manifest *manifest.Manifest `json:"manifest"`
|
||||
ScriptHash util.Uint160 `json:"hash"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
func (cs *Contract) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(&contractJSON{
|
||||
ID: cs.ID,
|
||||
Script: cs.Script,
|
||||
Manifest: &cs.Manifest,
|
||||
ScriptHash: cs.ScriptHash(),
|
||||
})
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
func (cs *Contract) UnmarshalJSON(data []byte) error {
|
||||
var cj contractJSON
|
||||
if err := json.Unmarshal(data, &cj); err != nil {
|
||||
return err
|
||||
} else if cj.Manifest == nil {
|
||||
return errors.New("empty manifest")
|
||||
}
|
||||
cs.ID = cj.ID
|
||||
cs.Script = cj.Script
|
||||
cs.Manifest = *cj.Manifest
|
||||
cs.createHash()
|
||||
return nil
|
||||
return hash.Hash160(w.Bytes())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue