Implemented rcp method GetAssetState (#103)
* Fix missing dot in configPath * Add rpc GetAssetState method * Update rpc README.md * Update version to 0.45.10
This commit is contained in:
parent
de45c58551
commit
e2f42e92a0
10 changed files with 120 additions and 7 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
0.44.11
|
||||
0.45.11
|
||||
|
|
|
@ -40,7 +40,7 @@ func startServer(ctx *cli.Context) error {
|
|||
net = config.ModeMainNet
|
||||
}
|
||||
|
||||
configPath := "./config"
|
||||
configPath := "../config"
|
||||
if argCp := ctx.String("config-path"); argCp != "" {
|
||||
configPath = argCp
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ type AssetState struct {
|
|||
Available util.Fixed8
|
||||
Precision uint8
|
||||
FeeMode uint8
|
||||
FeeAddress util.Uint160
|
||||
Owner *crypto.PublicKey
|
||||
Admin util.Uint160
|
||||
Issuer util.Uint160
|
||||
|
@ -72,6 +73,9 @@ func (a *AssetState) DecodeBinary(r io.Reader) error {
|
|||
if err := binary.Read(r, binary.LittleEndian, &a.FeeMode); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Read(r, binary.LittleEndian, &a.FeeAddress); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.Owner = &crypto.PublicKey{}
|
||||
if err := a.Owner.DecodeBinary(r); err != nil {
|
||||
|
@ -115,6 +119,11 @@ func (a *AssetState) EncodeBinary(w io.Writer) error {
|
|||
if err := binary.Write(w, binary.LittleEndian, a.FeeMode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := binary.Write(w, binary.LittleEndian, a.FeeAddress); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.Owner.EncodeBinary(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -129,3 +138,15 @@ func (a *AssetState) EncodeBinary(w io.Writer) error {
|
|||
}
|
||||
return binary.Write(w, binary.LittleEndian, a.IsFrozen)
|
||||
}
|
||||
|
||||
// Get the asset name based on its type.
|
||||
func (a *AssetState) GetName() string {
|
||||
|
||||
if a.AssetType == transaction.GoverningToken {
|
||||
return "NEO"
|
||||
} else if a.AssetType == transaction.UtilityToken {
|
||||
return "NEOGas"
|
||||
}
|
||||
|
||||
return a.Name
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/CityOfZion/neo-go/config"
|
||||
//"github.com/CityOfZion/neo-go/pkg/core"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
|
@ -527,6 +528,20 @@ func (bc *Blockchain) HeaderHeight() uint32 {
|
|||
return uint32(bc.headerListLen() - 1)
|
||||
}
|
||||
|
||||
func (bc *Blockchain) GetAssetState(assetID util.Uint256) *AssetState {
|
||||
|
||||
var as *AssetState
|
||||
bc.Store.Seek(storage.STAsset.Bytes(), func(k, v []byte) {
|
||||
var a AssetState
|
||||
a.DecodeBinary(bytes.NewReader(v))
|
||||
if a.ID == assetID {
|
||||
as = &a
|
||||
}
|
||||
})
|
||||
|
||||
return as
|
||||
}
|
||||
|
||||
func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
|
||||
buf := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(buf, index)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package core
|
||||
|
||||
import "github.com/CityOfZion/neo-go/pkg/util"
|
||||
import (
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Blockchainer is an interface that abstract the implementation
|
||||
// of the blockchain.
|
||||
|
@ -15,4 +17,5 @@ type Blockchainer interface {
|
|||
CurrentBlockHash() util.Uint256
|
||||
HasBlock(util.Uint256) bool
|
||||
HasTransaction(util.Uint256) bool
|
||||
GetAssetState(util.Uint256) *AssetState
|
||||
}
|
||||
|
|
|
@ -138,11 +138,11 @@ func (p ECPoint) EncodeBinary(w io.Writer) error {
|
|||
// String implements the Stringer interface.
|
||||
func (p *ECPoint) String() string {
|
||||
if p.IsInfinity() {
|
||||
return "(inf, inf)"
|
||||
return "00"
|
||||
}
|
||||
bx := hex.EncodeToString(p.X.Bytes())
|
||||
by := hex.EncodeToString(p.Y.Bytes())
|
||||
return fmt.Sprintf("(%s, %s)", bx, by)
|
||||
return fmt.Sprintf("%s%s", bx, by)
|
||||
}
|
||||
|
||||
// IsInfinity checks if point P is infinity on EllipticCurve ec.
|
||||
|
|
|
@ -29,6 +29,9 @@ func (chain testChain) GetBlock(hash util.Uint256) (*core.Block, error) {
|
|||
func (chain testChain) GetHeaderHash(int) util.Uint256 {
|
||||
return util.Uint256{}
|
||||
}
|
||||
func (chain testChain) GetAssetState(util.Uint256) *core.AssetState {
|
||||
return nil
|
||||
}
|
||||
func (chain testChain) CurrentHeaderHash() util.Uint256 {
|
||||
return util.Uint256{}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ which would yield the response:
|
|||
| `submitblock` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `gettxout` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `invoke` | No | VM |
|
||||
| `getassetstate` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `getassetstate` | Yes |-|
|
||||
| `getpeers` | Yes | - |
|
||||
| `getversion` | Yes | - |
|
||||
| `getconnectioncount` | Yes | - |
|
||||
|
|
|
@ -179,9 +179,35 @@ Methods:
|
|||
|
||||
results = peers
|
||||
|
||||
case "validateaddress", "getblocksysfee", "getcontractstate", "getrawmempool", "getrawtransaction", "getstorage", "submitblock", "gettxout", "invoke", "invokefunction", "invokescript", "sendrawtransaction", "getaccountstate", "getassetstate":
|
||||
case "validateaddress", "getblocksysfee", "getcontractstate", "getrawmempool", "getrawtransaction", "getstorage", "submitblock", "gettxout", "invoke", "invokefunction", "invokescript", "sendrawtransaction", "getaccountstate":
|
||||
results = "TODO"
|
||||
|
||||
case "getassetstate":
|
||||
var err error
|
||||
|
||||
param, exists := reqParams.ValueAt(0)
|
||||
if !exists {
|
||||
err = errors.New("Param at index at 0 doesn't exist")
|
||||
resultsErr = NewInvalidParamsError(err.Error(), err)
|
||||
break
|
||||
}
|
||||
|
||||
if param.Type != "string" {
|
||||
err = errors.New("Param need to be a string")
|
||||
resultsErr = NewInvalidParamsError(err.Error(), err)
|
||||
break
|
||||
}
|
||||
|
||||
paramAssetID, err := util.Uint256DecodeString(param.StringVal)
|
||||
|
||||
as := s.chain.GetAssetState(paramAssetID)
|
||||
|
||||
if as != nil {
|
||||
results = wrappers.NewAssetState(as)
|
||||
} else {
|
||||
results = "Invalid assetid"
|
||||
}
|
||||
|
||||
default:
|
||||
resultsErr = NewMethodNotFoundError(fmt.Sprintf("Method '%s' not supported", req.Method), nil)
|
||||
}
|
||||
|
|
45
pkg/rpc/wrappers/asset_state.go
Normal file
45
pkg/rpc/wrappers/asset_state.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package wrappers
|
||||
|
||||
import (
|
||||
"github.com/CityOfZion/neo-go/pkg/core"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// AssetState wrapper used for the representation of
|
||||
// core.AssetState on the RPC Server.
|
||||
type AssetState struct {
|
||||
ID util.Uint256 `json:"assetId"`
|
||||
AssetType transaction.AssetType `json:"assetType"`
|
||||
Name string `json:"name"`
|
||||
Amount util.Fixed8 `json:"amount"`
|
||||
Available util.Fixed8 `json:"available"`
|
||||
Precision uint8 `json:"precision"`
|
||||
FeeMode uint8 `json:"fee"`
|
||||
FeeAddress util.Uint160 `json:"address"`
|
||||
Owner string `json:"owner"`
|
||||
Admin string `json:"admin"`
|
||||
Issuer string `json:"issuer"`
|
||||
Expiration uint32 `json:"expiration"`
|
||||
IsFrozen bool `json:"is_frozen"`
|
||||
}
|
||||
|
||||
// NewAssetState creates a new AssetState wrapper.
|
||||
func NewAssetState(a *core.AssetState) AssetState {
|
||||
return AssetState{
|
||||
ID: a.ID,
|
||||
AssetType: a.AssetType,
|
||||
Name: a.GetName(),
|
||||
Amount: a.Amount,
|
||||
Available: a.Available,
|
||||
Precision: a.Precision,
|
||||
FeeMode: a.FeeMode,
|
||||
FeeAddress: a.FeeAddress,
|
||||
Owner: a.Owner.String(),
|
||||
Admin: crypto.AddressFromUint160(a.Admin),
|
||||
Issuer: crypto.AddressFromUint160(a.Issuer),
|
||||
Expiration: a.Expiration,
|
||||
IsFrozen: a.IsFrozen,
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue