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 }