forked from TrueCloudLab/neoneo-go
core: fix contract state's Properties to use PropertyState
PublishTX only had one of these flags, but newer contracts (created via the interop function) can have more and these flags are aggregated into one field that uses PropertyState enumeration (it's used to publish contract, so supposedly it's also a nice choice for contract state storage).
This commit is contained in:
parent
acb7ef7fbd
commit
238c590ddb
4 changed files with 67 additions and 29 deletions
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/CityOfZion/neo-go/pkg/vm"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -390,11 +391,15 @@ func (bc *Blockchain) storeBlock(block *Block) error {
|
|||
case *transaction.EnrollmentTX:
|
||||
case *transaction.StateTX:
|
||||
case *transaction.PublishTX:
|
||||
var properties smartcontract.PropertyState
|
||||
if t.NeedStorage {
|
||||
properties |= smartcontract.HasStorage
|
||||
}
|
||||
contract := &ContractState{
|
||||
Script: t.Script,
|
||||
ParamList: t.ParamList,
|
||||
ReturnType: t.ReturnType,
|
||||
HasStorage: t.NeedStorage,
|
||||
Properties: properties,
|
||||
Name: t.Name,
|
||||
CodeVersion: t.CodeVersion,
|
||||
Author: t.Author,
|
||||
|
|
|
@ -16,14 +16,12 @@ type ContractState struct {
|
|||
Script []byte
|
||||
ParamList []smartcontract.ParamType
|
||||
ReturnType smartcontract.ParamType
|
||||
Properties []byte
|
||||
Properties smartcontract.PropertyState
|
||||
Name string
|
||||
CodeVersion string
|
||||
Author string
|
||||
Email string
|
||||
Description string
|
||||
HasStorage bool
|
||||
HasDynamicInvoke bool
|
||||
|
||||
scriptHash util.Uint160
|
||||
}
|
||||
|
@ -52,14 +50,12 @@ func (a *ContractState) DecodeBinary(br *io.BinReader) {
|
|||
a.ParamList[k] = smartcontract.ParamType(paramBytes[k])
|
||||
}
|
||||
br.ReadLE(&a.ReturnType)
|
||||
a.Properties = br.ReadBytes()
|
||||
br.ReadLE(&a.Properties)
|
||||
a.Name = br.ReadString()
|
||||
a.CodeVersion = br.ReadString()
|
||||
a.Author = br.ReadString()
|
||||
a.Email = br.ReadString()
|
||||
a.Description = br.ReadString()
|
||||
br.ReadLE(&a.HasStorage)
|
||||
br.ReadLE(&a.HasDynamicInvoke)
|
||||
a.createHash()
|
||||
}
|
||||
|
||||
|
@ -71,14 +67,12 @@ func (a *ContractState) EncodeBinary(bw *io.BinWriter) {
|
|||
bw.WriteLE(a.ParamList[k])
|
||||
}
|
||||
bw.WriteLE(a.ReturnType)
|
||||
bw.WriteBytes(a.Properties)
|
||||
bw.WriteLE(a.Properties)
|
||||
bw.WriteString(a.Name)
|
||||
bw.WriteString(a.CodeVersion)
|
||||
bw.WriteString(a.Author)
|
||||
bw.WriteString(a.Email)
|
||||
bw.WriteString(a.Description)
|
||||
bw.WriteLE(a.HasStorage)
|
||||
bw.WriteLE(a.HasDynamicInvoke)
|
||||
}
|
||||
|
||||
// ScriptHash returns a contract script hash.
|
||||
|
@ -93,3 +87,18 @@ func (a *ContractState) ScriptHash() util.Uint160 {
|
|||
func (a *ContractState) createHash() {
|
||||
a.scriptHash = hash.Hash160(a.Script)
|
||||
}
|
||||
|
||||
// HasStorage checks whether the contract has storage property set.
|
||||
func (cs *ContractState) HasStorage() bool {
|
||||
return (cs.Properties & smartcontract.HasStorage) != 0
|
||||
}
|
||||
|
||||
// HasDynamicInvoke checks whether the contract has dynamic invoke property set.
|
||||
func (cs *ContractState) HasDynamicInvoke() bool {
|
||||
return (cs.Properties & smartcontract.HasDynamicInvoke) != 0
|
||||
}
|
||||
|
||||
// IsPayable checks whether the contract has payable property set.
|
||||
func (cs *ContractState) IsPayable() bool {
|
||||
return (cs.Properties & smartcontract.IsPayable) != 0
|
||||
}
|
||||
|
|
|
@ -16,14 +16,12 @@ func TestEncodeDecodeContractState(t *testing.T) {
|
|||
Script: script,
|
||||
ParamList: []smartcontract.ParamType{smartcontract.StringType, smartcontract.IntegerType, smartcontract.Hash160Type},
|
||||
ReturnType: smartcontract.BoolType,
|
||||
Properties: []byte("smth"),
|
||||
Properties: smartcontract.HasStorage,
|
||||
Name: "Contracto",
|
||||
CodeVersion: "1.0.0",
|
||||
Author: "Joe Random",
|
||||
Email: "joe@example.com",
|
||||
Description: "Test contract",
|
||||
HasStorage: true,
|
||||
HasDynamicInvoke: false,
|
||||
}
|
||||
|
||||
assert.Equal(t, hash.Hash160(script), contract.ScriptHash())
|
||||
|
@ -37,3 +35,18 @@ func TestEncodeDecodeContractState(t *testing.T) {
|
|||
assert.Equal(t, contract, contractDecoded)
|
||||
assert.Equal(t, contract.ScriptHash(), contractDecoded.ScriptHash())
|
||||
}
|
||||
|
||||
func TestContractStateProperties(t *testing.T) {
|
||||
flaggedContract := ContractState{
|
||||
Properties: smartcontract.HasStorage | smartcontract.HasDynamicInvoke | smartcontract.IsPayable,
|
||||
}
|
||||
nonFlaggedContract := ContractState{
|
||||
ReturnType: smartcontract.BoolType,
|
||||
}
|
||||
assert.Equal(t, true, flaggedContract.HasStorage())
|
||||
assert.Equal(t, true, flaggedContract.HasDynamicInvoke())
|
||||
assert.Equal(t, true, flaggedContract.IsPayable())
|
||||
assert.Equal(t, false, nonFlaggedContract.HasStorage())
|
||||
assert.Equal(t, false, nonFlaggedContract.HasDynamicInvoke())
|
||||
assert.Equal(t, false, nonFlaggedContract.IsPayable())
|
||||
}
|
||||
|
|
|
@ -18,6 +18,17 @@ const (
|
|||
ArrayType
|
||||
)
|
||||
|
||||
// PropertyState represents contract properties (flags).
|
||||
type PropertyState byte
|
||||
|
||||
// List of supported properties.
|
||||
const (
|
||||
NoProperties = 0
|
||||
HasStorage PropertyState = 1 << iota
|
||||
HasDynamicInvoke
|
||||
IsPayable
|
||||
)
|
||||
|
||||
// Parameter represents a smart contract parameter.
|
||||
type Parameter struct {
|
||||
// Type of the parameter
|
||||
|
|
Loading…
Reference in a new issue