github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/core/chaincode/shim/interfaces.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package shim
    18  
    19  import (
    20  	"github.com/golang/protobuf/ptypes/timestamp"
    21  
    22  	"math/big"
    23  
    24  	"github.com/inklabsfoundation/inkchain/core/wallet"
    25  	"github.com/inklabsfoundation/inkchain/protos/ledger/queryresult"
    26  	"github.com/inklabsfoundation/inkchain/protos/ledger/transet/kvtranset"
    27  	pb "github.com/inklabsfoundation/inkchain/protos/peer"
    28  )
    29  
    30  // Chaincode interface must be implemented by all chaincodes. The inkchain runs
    31  // the transactions by calling these functions as specified.
    32  type Chaincode interface {
    33  	// Init is called during Instantiate transaction after the chaincode container
    34  	// has been established for the first time, allowing the chaincode to
    35  	// initialize its internal data
    36  	Init(stub ChaincodeStubInterface) pb.Response
    37  
    38  	// Invoke is called to update or query the ledger in a proposal transaction.
    39  	// Updated state variables are not committed to the ledger until the
    40  	// transaction is committed.
    41  	Invoke(stub ChaincodeStubInterface) pb.Response
    42  }
    43  
    44  // ChaincodeStubInterface is used by deployable chaincode apps to access and
    45  // modify their ledgers
    46  type ChaincodeStubInterface interface {
    47  	// GetArgs returns the arguments intended for the chaincode Init and Invoke
    48  	// as an array of byte arrays.
    49  	GetArgs() [][]byte
    50  
    51  	// GetStringArgs returns the arguments intended for the chaincode Init and
    52  	// Invoke as a string array. Only use GetStringArgs if the client passes
    53  	// arguments intended to be used as strings.
    54  	GetStringArgs() []string
    55  
    56  	// GetFunctionAndParameters returns the first argument as the function
    57  	// name and the rest of the arguments as parameters in a string array.
    58  	// Only use GetFunctionAndParameters if the client passes arguments intended
    59  	// to be used as strings.
    60  	GetFunctionAndParameters() (string, []string)
    61  
    62  	// GetArgsSlice returns the arguments intended for the chaincode Init and
    63  	// Invoke as a byte array
    64  	GetArgsSlice() ([]byte, error)
    65  
    66  	// GetTxID returns the tx_id of the transaction proposal (see ChannelHeader
    67  	// in protos/common/common.proto)
    68  	GetTxID() string
    69  
    70  	// InvokeChaincode locally calls the specified chaincode `Invoke` using the
    71  	// same transaction context; that is, chaincode calling chaincode doesn't
    72  	// create a new transaction message.
    73  	// If the called chaincode is on the same channel, it simply adds the called
    74  	// chaincode read set and write set to the calling transaction.
    75  	// If the called chaincode is on a different channel,
    76  	// only the Response is returned to the calling chaincode; any PutState calls
    77  	// from the called chaincode will not have any effect on the ledger; that is,
    78  	// the called chaincode on a different channel will not have its read set
    79  	// and write set applied to the transaction. Only the calling chaincode's
    80  	// read set and write set will be applied to the transaction. Effectively
    81  	// the called chaincode on a different channel is a `Query`, which does not
    82  	// participate in state validation checks in subsequent commit phase.
    83  	// If `channel` is empty, the caller's channel is assumed.
    84  	InvokeChaincode(chaincodeName string, args [][]byte, channel string) pb.Response
    85  
    86  	// GetState returns the value of the specified `key` from the
    87  	// ledger. Note that GetState doesn't read data from the writeset, which
    88  	// has not been committed to the ledger. In other words, GetState doesn't
    89  	// consider data modified by PutState that has not been committed.
    90  	// If the key does not exist in the state database, (nil, nil) is returned.
    91  	GetState(key string) ([]byte, error)
    92  
    93  	// PutState puts the specified `key` and `value` into the transaction's
    94  	// writeset as a data-write proposal. PutState doesn't effect the ledger
    95  	// until the transaction is validated and successfully committed.
    96  	// Simple keys must not be an empty string and must not start with null
    97  	// character (0x00), in order to avoid range query collisions with
    98  	// composite keys, which internally get prefixed with 0x00 as composite
    99  	// key namespace.
   100  	PutState(key string, value []byte) error
   101  
   102  	// DelState records the specified `key` to be deleted in the writeset of
   103  	// the transaction proposal. The `key` and its value will be deleted from
   104  	// the ledger when the transaction is validated and successfully committed.
   105  	DelState(key string) error
   106  
   107  	// GetStateByRange returns a range iterator over a set of keys in the
   108  	// ledger. The iterator can be used to iterate over all keys
   109  	// between the startKey (inclusive) and endKey (exclusive).
   110  	// The keys are returned by the iterator in lexical order. Note
   111  	// that startKey and endKey can be empty string, which implies unbounded range
   112  	// query on start or end.
   113  	// Call Close() on the returned StateQueryIteratorInterface object when done.
   114  	// The query is re-executed during validation phase to ensure result set
   115  	// has not changed since transaction endorsement (phantom reads detected).
   116  	GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error)
   117  
   118  	// GetStateByPartialCompositeKey queries the state in the ledger based on
   119  	// a given partial composite key. This function returns an iterator
   120  	// which can be used to iterate over all composite keys whose prefix matches
   121  	// the given partial composite key. The `objectType` and attributes are
   122  	// expected to have only valid utf8 strings and should not contain
   123  	// U+0000 (nil byte) and U+10FFFF (biggest and unallocated code point).
   124  	// See related functions SplitCompositeKey and CreateCompositeKey.
   125  	// Call Close() on the returned StateQueryIteratorInterface object when done.
   126  	// The query is re-executed during validation phase to ensure result set
   127  	// has not changed since transaction endorsement (phantom reads detected).
   128  	GetStateByPartialCompositeKey(objectType string, keys []string) (StateQueryIteratorInterface, error)
   129  
   130  	// CreateCompositeKey combines the given `attributes` to form a composite
   131  	// key. The objectType and attributes are expected to have only valid utf8
   132  	// strings and should not contain U+0000 (nil byte) and U+10FFFF
   133  	// (biggest and unallocated code point).
   134  	// The resulting composite key can be used as the key in PutState().
   135  	CreateCompositeKey(objectType string, attributes []string) (string, error)
   136  
   137  	// SplitCompositeKey splits the specified key into attributes on which the
   138  	// composite key was formed. Composite keys found during range queries
   139  	// or partial composite key queries can therefore be split into their
   140  	// composite parts.
   141  	SplitCompositeKey(compositeKey string) (string, []string, error)
   142  
   143  	// GetQueryResult performs a "rich" query against a state database. It is
   144  	// only supported for state databases that support rich query,
   145  	// e.g.CouchDB. The query string is in the native syntax
   146  	// of the underlying state database. An iterator is returned
   147  	// which can be used to iterate (next) over the query result set.
   148  	// The query is NOT re-executed during validation phase, phantom reads are
   149  	// not detected. That is, other committed transactions may have added,
   150  	// updated, or removed keys that impact the result set, and this would not
   151  	// be detected at validation/commit time.  Applications susceptible to this
   152  	// should therefore not use GetQueryResult as part of transactions that update
   153  	// ledger, and should limit use to read-only chaincode operations.
   154  	GetQueryResult(query string) (StateQueryIteratorInterface, error)
   155  
   156  	// GetHistoryForKey returns a history of key values across time.
   157  	// For each historic key update, the historic value and associated
   158  	// transaction id and timestamp are returned. The timestamp is the
   159  	// timestamp provided by the client in the proposal header.
   160  	// GetHistoryForKey requires peer configuration
   161  	// core.ledger.history.enableHistoryDatabase to be true.
   162  	// The query is NOT re-executed during validation phase, phantom reads are
   163  	// not detected. That is, other committed transactions may have updated
   164  	// the key concurrently, impacting the result set, and this would not be
   165  	// detected at validation/commit time. Applications susceptible to this
   166  	// should therefore not use GetHistoryForKey as part of transactions that
   167  	// update ledger, and should limit use to read-only chaincode operations.
   168  	GetHistoryForKey(key string) (HistoryQueryIteratorInterface, error)
   169  
   170  	// GetCreator returns `SignatureHeader.Creator` (e.g. an identity)
   171  	// of the `SignedProposal`. This is the identity of the agent (or user)
   172  	// submitting the transaction.
   173  	GetCreator() ([]byte, error)
   174  
   175  	// GetTransient returns the `ChaincodeProposalPayload.Transient` field.
   176  	// It is a map that contains data (e.g. cryptographic material)
   177  	// that might be used to implement some form of application-level
   178  	// confidentiality. The contents of this field, as prescribed by
   179  	// `ChaincodeProposalPayload`, are supposed to always
   180  	// be omitted from the transaction and excluded from the ledger.
   181  	GetTransient() (map[string][]byte, error)
   182  
   183  	// GetBinding returns the transaction binding
   184  	GetBinding() ([]byte, error)
   185  
   186  	// GetSignedProposal returns the SignedProposal object, which contains all
   187  	// data elements part of a transaction proposal.
   188  	GetSignedProposal() (*pb.SignedProposal, error)
   189  
   190  	// GetTxTimestamp returns the timestamp when the transaction was created. This
   191  	// is taken from the transaction ChannelHeader, therefore it will indicate the
   192  	// client's timestamp, and will have the same value across all endorsers.
   193  	GetTxTimestamp() (*timestamp.Timestamp, error)
   194  
   195  	// SetEvent allows the chaincode to propose an event on the transaction
   196  	// proposal. If the transaction is validated and successfully committed,
   197  	// the event will be delivered to the current event listeners.
   198  	SetEvent(name string, payload []byte) error
   199  
   200  	// Interfaces added by Inklabs Foundation
   201  
   202  	// Transfer implements atomic balance changes. It allows an transaction of
   203  	// a specific type of token (e.g., INK) from one account to another one.
   204  	Transfer(to string, balanceType string, amount *big.Int) error
   205  
   206  	MultiTransfer(trans *kvtranset.KVTranSet) error
   207  
   208  	// GetAccount returns the account information of the given address.
   209  	// Account information includes its address, balances of different kinds of tokens,
   210  	// and a counter.
   211  	GetAccount(address string) (*wallet.Account, error)
   212  
   213  	IssueToken(address string, balanceType string, amount *big.Int) error
   214  
   215  	// GetSender returns the sender's address. The address is
   216  	// revealed from his/her signature.
   217  	GetSender() (string, error)
   218  
   219  	// GetSenderPubKey returns the sender's public key.
   220  	GetSenderPubKey() (string, error)
   221  
   222  	//CalcFeeByInvoke returns the fee of operate, And only can be called
   223  	//by invoke
   224  	CalcFeeByInvoke() (*big.Int, error)
   225  
   226  	//CalcFee returns the fee of passed content
   227  	CalcFee(content string) (*big.Int, error)
   228  
   229  	//sign data
   230  	Sign(data []byte) (sign string, err error)
   231  
   232  	//verify signature from Sign
   233  	Verify(sign string, data []byte, address string) (result bool, err error)
   234  }
   235  
   236  // CommonIteratorInterface allows a chaincode to check whether any more result
   237  // to be fetched from an iterator and close it when done.
   238  type CommonIteratorInterface interface {
   239  	// HasNext returns true if the range query iterator contains additional keys
   240  	// and values.
   241  	HasNext() bool
   242  
   243  	// Close closes the iterator. This should be called when done
   244  	// reading from the iterator to free up resources.
   245  	Close() error
   246  }
   247  
   248  // StateQueryIteratorInterface allows a chaincode to iterate over a set of
   249  // key/value pairs returned by range and execute query.
   250  type StateQueryIteratorInterface interface {
   251  	// Inherit HasNext() and Close()
   252  	CommonIteratorInterface
   253  
   254  	// Next returns the next key and value in the range and execute query iterator.
   255  	Next() (*queryresult.KV, error)
   256  }
   257  
   258  // HistoryQueryIteratorInterface allows a chaincode to iterate over a set of
   259  // key/value pairs returned by a history query.
   260  type HistoryQueryIteratorInterface interface {
   261  	// Inherit HasNext() and Close()
   262  	CommonIteratorInterface
   263  
   264  	// Next returns the next key and value in the history query iterator.
   265  	Next() (*queryresult.KeyModification, error)
   266  }
   267  
   268  // MockQueryIteratorInterface allows a chaincode to iterate over a set of
   269  // key/value pairs returned by range query.
   270  // TODO: Once the execute query and history query are implemented in MockStub,
   271  // we need to update this interface
   272  type MockQueryIteratorInterface interface {
   273  	StateQueryIteratorInterface
   274  }