# 鏁翠綋鏋舵瀯璇存槑 ## 閫昏緫鏋舵瀯 闀垮畨閾鹃€昏緫鏋舵瀯濡備笅鍥炬墍绀恒€備富瑕佸寘鍚互涓嬪厓绱狅細 - 鍏辫瘑鑺傜偣锛坄consensus node`锛夛細鍙備笌鍖哄潡閾剧綉缁滀腑鍏辫瘑鎶曠エ銆佷氦鏄撴墽琛屻€佸尯鍧楅獙璇佸拰璁拌处鐨勮妭鐐广€� - 鍚屾鑺傜偣 (`sync node`)锛氭垨绉拌璇佽妭鐐癸紝鍙備笌鍖哄潡鍜屼氦鏄撳悓姝ャ€佸尯鍧楅獙璇侊紝浜ゆ槗鎵ц锛屽苟璁板綍瀹屾暣璐︽湰鏁版嵁锛屼絾涓嶅弬涓庡叡璇嗘姇绁ㄣ€� - 杞昏妭鐐� (`light node`)锛氬弬涓庡悓姝ュ拰鏍¢獙鍖哄潡澶翠俊鎭€侀獙璇佷氦鏄撳瓨鍦ㄦ€х殑鑺傜偣銆� - SDK锛氬府鍔╃敤鎴烽€氳繃RPC鍜屽尯鍧楅摼缃戠粶杩涜杩炴帴锛屽畬鎴愬悎绾﹀垱寤恒€佽皟鐢ㄣ€侀摼绠$悊绛夊姛鑳姐€� - 鍖哄潡閾炬祻瑙堝櫒 (`ChainMaker broswer`)锛氶€氳繃鍙鍖栫晫闈负鐢ㄦ埛灞曠ず鍖哄潡淇℃伅銆佷氦鏄撲俊鎭€佽妭鐐逛俊鎭瓑鍖哄潡閾句俊鎭€� - 绠$悊骞冲彴 (`management platform`)锛氶€氳繃鍙鍖栫晫闈㈡柟渚跨敤鎴峰閾捐繘琛岀鐞嗐€佷俊鎭祻瑙堝拰璧勬簮鐩戞帶绛夈€� - 鍚堢害IDE (`contract IDE`)锛氭櫤鑳藉悎绾﹀湪绾垮紑鍙戠幆澧冿紝闀垮畨閾炬墍鏈夊悎绾︽敮鎸佽瑷€鍧囧彲鍦ㄨIDE涓婂紑鍙戝拰缂栬瘧銆� - 鍛戒护琛屽伐鍏烽泦 (`ChainMaker CLI, cmc`)锛氫娇鐢ㄦ埛鍙互鐢ㄥ懡浠よ鐨勬柟寮忓閾捐繘琛岄儴缃插拰绠$悊鎿嶄綔锛屼緥濡傝瘉涔︾敓鎴愩€侀摼閰嶇疆銆佷氦鏄撳彂閫佺瓑銆� <img loading="lazy" src="../images/Architecture-Logical.png" alt="鏁翠綋鏋舵瀯-閫昏緫鏋舵瀯" style="zoom:70%;" /> ## 灞傜骇鏋舵瀯 鑷笅鑰屼笂锛岄暱瀹夐摼鐢变互涓嬪眰绾ф瀯鎴愶細 - 鍩虹璁炬柦灞傦細鍏湁浜戙€佺鏈変簯锛屽寘鎷櫄鎷熸満銆佺墿鐞嗘満绛夛紝涓洪暱瀹夐摼鎻愪緵鍩虹杩愯鐜銆� - 瀛樺偍璧勬簮灞傦細涓洪暱瀹夐摼鑺傜偣鎻愪緵鏁版嵁瀛樺偍鏈嶅姟锛屽叿浣撴儏鍐靛彲鍙傝[鏁版嵁瀛樺偍](./鏁版嵁瀛樺偍.md)绔犺妭銆� - 鍩虹缁勪欢灞傦細涓洪暱瀹夐摼鑺傜偣鎻愪緵瀵嗙爜瀛︺€侀厤缃€佹棩蹇椼€佸父鐢ㄦ暟鎹粨鏋勭瓑閫氱敤鎶€鏈粍浠讹紝鍏蜂綋鍙[chainmaker-common](https://git.chainmaker.org.cn/chainmaker/chainmaker-common)椤圭洰銆� - 鏍稿績妯″潡灞傦細闀垮畨閾惧叡璇嗙畻娉曘€佹牳蹇冨紩鎿庛€佽櫄鎷熸満绛夋牳蹇冩ā鍧楋紝鏍稿績妯″潡鍧囬噰鐢ㄥ彲鎻掓嫈璁捐锛屼负鍙閰嶅尯鍧楅摼濂犲畾鍩虹銆� - 鎺ュ叆灞傦細澶氳瑷€閾維DK锛屾柟渚垮簲鐢ㄥ紑鍙戣€呬笌閾句氦浜掋€� - 鍓嶇搴旂敤灞傦細鍖呮嫭鍖哄潡閾剧鐞嗗钩鍙般€佸尯鍧楅摼娴忚鍣ㄣ€佸悎绾﹀紑鍙慖DE绛夛紝鏂逛究鐢ㄦ埛鐩存帴璁块棶鍖哄潡閾惧簳灞傚钩鍙般€� <img loading="lazy" src="../images/Architecture-Hierarchy.png" alt="鏁翠綋鏋舵瀯-灞傜骇鏋舵瀯" style="width:800px;" /> <br><br> ## 鏍稿績娴佺▼ 闀垮畨閾惧尯鍧椾骇鐢熺殑鏍稿績娴佺▼濡備笅鍥炬墍绀猴紝涓昏鍖呮嫭锛� 1. 鎻愯鍊欓€夊尯鍧椼€傚尯鍧楁彁璁妭鐐逛粠浜ゆ槗姹犻€夊彇涓€鎵逛氦鏄擄紝骞惰璋冨害鎵ц寰楀埌缁撴灉锛岀敓鎴怐AG锛屽苟灏嗗尯鍧楀拰DAG骞挎挱銆� 2. 鍏辫瘑鍊欓€夊尯鍧椼€傚熀浜庨摼涓婄殑鍏辫瘑鏈哄埗锛屽鍊欓€夊尯鍧楄繘琛屽叡璇嗘姇绁ㄣ€� 3. 楠岃瘉鍊欓€夊尯鍧椼€傚湪鍏辫瘑杩囩▼涓紝缃戠粶涓叾浠栬妭鐐归拡瀵规彁璁殑鍊欓€夊尯鍧楄繘琛屾纭€ч獙璇併€� 4. 鎵ц鍊欓€夊尯鍧椼€傚皢瀹屾垚鍏辫瘑鎶曠エ鐨勫尯鍧楁彁浜よ褰曡嚦璐︽湰锛屽苟浠庝氦鏄撶紦瀛樹腑绉婚櫎銆� <img loading="lazy" src="../images/CoreProcesses-block-generation.png" alt="鏍稿績娴佺▼" style="zoom:80%;" /> <br><br> ## 鏁版嵁缁撴瀯 闀垮畨閾撅紙ChainMaker锛夋牳蹇冩暟鎹粨鏋勭殕閲囩敤protobuf3璇硶杩涜瀹氫箟锛屼互鏂逛究鍦ㄤ笉鍚岀殑璇█涔嬮棿杩涜閫氫俊銆傞暱瀹夐摼鏁版嵁缁撴瀯妯″瀷瀹氫箟鍦╗pb](https://git.chainmaker.org.cn/chainmaker/pb/-/tree/v2.3.2)椤圭洰涓嬶紝骞舵寜鍔熻兘鍜屼娇鐢ㄨ寖鍥达紝鍒嗕负锛� * `accesscontrol` 涓庤闂帶鍒剁浉鍏崇殑鐢ㄦ埛璐︽埛銆佺粍缁囪鑹茬瓑瀵硅薄 * `api` 涓庡鎴风SDK鐩稿叧鐨勫璞� * `archivecenter` 涓庡綊妗d腑蹇冧氦浜掓帴鍙e強瀵硅薄瀹氫箟* * `common` 鏍稿績鍖哄潡澶淬€佷氦鏄撱€佺粨鏋滃璞� * `config` 鍖哄潡鑺傜偣閰嶇疆鍜岀綉缁滈厤缃瓑鐩稿叧瀵硅薄 * `consensus` 涓庡叡璇嗙浉鍏崇殑瀵硅薄锛屼笉鍚岀殑鍏辫瘑绠楁硶浼氭湁涓嶅悓鐨勫叡璇嗗璞� * `discovery` 鐢ㄤ簬P2P缃戠粶鍙戠幇鐨勫璞� * `net` 鐢ㄤ簬P2P缃戠粶骞挎挱鐨勬秷鎭璞� * `store` 杩涜璐︽湰鍜岀姸鎬佹暟鎹瓨鍌ㄤ娇鐢ㄧ殑瀵硅薄 * `sync` 鍚屾鏁版嵁浣跨敤鐨勭浉鍏冲璞� * `syscontract` 绯荤粺鍚堢害鍚嶇О/鏂规硶/鍙傛暟/甯搁噺瀵硅薄 * `tee` 闅愮璁$畻瀵硅薄 * `txfilter` 浜ゆ槗杩囨护鍣ㄧ姸鎬佸璞� * `txpool` 浜ゆ槗姹犵浉鍏冲璞� * `vm` 铏氭嫙鏈哄紩鎿庢墍闇€瀵硅薄 ChainMaker瀹樻柟鎻愪緵ChainMaker鍗忚鐨凣olang瀹炵幇锛屾牴鎹畃rotobuf3鏁版嵁妯″瀷瀹氫箟锛岀敓鎴怗olang浠g爜鍦ㄥ悓绾х殑pb-go鐩綍涓嬨€� ## 鏍稿績鏁版嵁妯″瀷 ### 鍖哄潡 #### 缁撴瀯绀烘剰鍥� <img loading="lazy" src="../images/DataStructure-BlockStructure.png" style="width:900px;" /> #### 鏁翠綋缁撴瀯 ```go // Block definition message Block { // header of the block BlockHeader header = 1; // execution sequence of intra block transactions, generated by proposer DAG dag = 2; // transaction list in this block repeated Transaction txs = 3; // stores the voting information of the current block // not included in block hash value calculation AdditionalData additional_data = 4; } // block additional data message AdditionalData { // extra data, with map type, excluded in hash calculation map<string, bytes> extra_data = 1; } // transaction execution sequence // Using adjacency table storage message DAG { // Neighbor node: related party transactions with reading and writing conflicts message Neighbor { repeated uint32 neighbors = 1; } // sequence number of transaction topological sort //the sequence number of the transaction topological sort associated with the transaction repeated Neighbor vertexes = 2; } ``` * Header锛氬尯鍧楀ご * Dag锛氬潡鍐呬氦鏄撶殑鎵ц渚濊禆椤哄簭锛岀敱Proposer鐢熸垚锛屽鏋滀负绌哄垯琛ㄧず鏈尯鍧楃殑鎵€鏈変氦鏄撻兘鍙互骞惰鎵ц锛屼笉瀛樺湪鍓嶅悗渚濊禆鍏崇郴 * Txs锛氬潡鍐呬氦鏄撳垪琛� * AdditionalData锛氬尯鍧椾骇鐢熶互鍚庨檮鍔犵殑鏁版嵁锛屼笉鍙備笌鍖哄潡鐨勬暎鍒楀€艰绠椼€傚彲鐢ㄤ簬瀛樺偍褰撳墠鍖哄潡鐨勬姇绁ㄤ俊鎭紝浜ゆ槗杩囨护绛夛紝鍏蜂綋鍐呭鏍规嵁閾句笂閰嶇疆鐨勫唴瀹硅€屽喅瀹� #### 鍖哄潡澶� ```go // header of the block message BlockHeader { // block version uint32 block_version = 1; // config block or normal block or other else BlockType block_type = 2; // blockchain identifier string chain_id = 3; // block height uint64 block_height = 4; // block hash (block identifier) bytes block_hash = 5; // previous block hash bytes pre_block_hash = 6; // previous config block height, used to trace and check if chain config is valid uint64 pre_conf_height = 7; // count of transactions uint32 tx_count = 8; // merkle root of transactions // used to verify the existence of this transactions bytes tx_root = 9; // Save the DAG feature summary, and hash the DAG after Pb serialization // hash of serialized DAG bytes dag_hash = 10; // The root hash of Merkle tree generated by read_write_set_digest in the result of each transaction in the block // used to verify the read-write set of the block bytes rw_set_root = 11; // the time stamp of the block int64 block_timestamp = 12; // consensus parameters // used to store information, include in block hash calculation bytes consensus_args = 13; // proposal node identifier accesscontrol.Member proposer = 14; // signature of proposer bytes signature = 15; } // BlockType specify block pack txs type enum BlockType { // Normal block, pack multi txs into one block NORMAL_BLOCK = 0; // Config block, only include 1 chain config update tx in this block CONFIG_BLOCK = 1; // Sql Contract init or upgrade block, only include 1 sql contract init or upgrade tx in this block CONTRACT_MGR_BLOCK = 2; // block.Txs[0] is a coinbase tx HAS_COINBASE = 4; } ``` - BlockVersion锛氬尯鍧楃増鏈� - BlockType: 鍖哄潡鐨勭被鍨嬶紝鎸夋墦鍖呯殑浜ゆ槗绫诲瀷锛屽垎涓烘櫘閫氬尯鍧椼€侀摼閰嶇疆鍖哄潡銆佸悎绾︾鐞嗗尯鍧楀拰鎷ユ湁Coinbase浜ゆ槗鐨勫尯鍧楃瓑銆� - ChainId锛氶摼鏍囪瘑锛岀敤浜庡尯鍒嗕笉鍚岀殑閾撅紝鍦ㄥ瀛愰摼鐨勬儏鍐典笅鍙尯鍒嗕笉鍚岀殑瀛愰摼 - BlockHeight锛氬尯鍧楅珮搴︼紝鍒涗笘鍖哄潡楂樺害涓�0 - BlockHash锛氭湰鍖哄潡鐨勬暎鍒楀€� - PreBlockHash锛氫笂涓尯鍧楃殑鏁e垪鍊� - PreConfHeight锛氫笂涓€娆′慨鏀归摼閰嶇疆鐨勫尯鍧楅珮搴︼紝鍦ㄨ繖涓珮搴︾殑鍖哄潡涓紝鍙瓨鍦ㄤ竴绗斾氦鏄擄紝涓洪厤缃氦鏄擄紝鍏朵腑淇濆瓨浜嗗尯鍧楅摼鐨勯厤缃俊鎭紝鍖呮嫭鏈尯鍧楀簲璇ラ噰鐢ㄧ殑鍏辫瘑绠楁硶锛屽姞瀵嗙畻娉曠瓑 - TxCount锛氫氦鏄撴暟閲� - TxRoot锛氬尯鍧椾氦鏄撶殑Merkle Root - DagHash锛氬綋鍓嶅尯鍧桪ag鐨勬暎鍒楀€� - RwSetRoot锛氬尯鍧楄鍐欓泦鐨凪erkle Root - BlockTimestamp锛氬尯鍧楃殑鏃堕棿鎴� - ConsensusArgs锛氬叡璇嗗弬鏁� - Proposer锛氬尯鍧楃殑鐢熸垚鑰呮爣璇� - Signature锛氬尯鍧楃敓鎴愯€呯殑绛惧悕 ### 浜ゆ槗缁撴瀯 #### 浜ゆ槗缁撴瀯绀烘剰鍥� <img loading="lazy" src="../images/DataStructure-Transaction.png" style="width:700px;" /> #### 浜ゆ槗缁撴瀯瀹氫箟 ```go // a transaction includes request and its result message Transaction { // payload Payload payload = 1; // sender account and signature EndorsementEntry sender = 2; // endorser accounts and signatures repeated EndorsementEntry endorsers = 3; // result of the transaction Result result = 4; // payer account and signature EndorsementEntry payer = 5; } ``` * Payload锛氫氦鏄撶殑杞借嵎鏁版嵁锛屼氦鏄撶殑鏍稿績淇℃伅 * Sender锛氫氦鏄撶殑鍙戣捣鑰呬俊鎭拰绛惧悕淇℃伅 * Endorsers锛氬绛炬儏鍐典笅锛屽涓儗涔︿汉鐨勮韩浠戒俊鎭拰鍏剁鍚嶄俊鎭� * Result锛氫氦鏄撶粨鏋滐紝鐢盤roposer鐢熸垚鍖哄潡鏃惰繘琛岃绠椼€佽祴鍊� * Payer锛氫唬浠榞as璐圭殑鐢ㄦ埛 #### 浜ゆ槗杞借嵎 ```go //transaction payload message Payload { // blockchain identifier string chain_id = 1; // transaction type TxType tx_type = 2; // transaction id set by sender, should be unique string tx_id = 3; // transaction timestamp, in unix timestamp format, seconds int64 timestamp = 4; // expiration timestamp in unix timestamp format // after that the transaction is invalid if it is not included in block yet int64 expiration_time = 5; // smart contract name string contract_name = 6; // invoke method string method = 7; // invoke parameters in k-v format repeated KeyValuePair parameters = 8; // sequence number, default is 0 uint64 sequence = 9; // gas price+gas limit; fee; timeout seconds; bytes limit = 10; } // transaction type definition enum TxType { // call a pre created contract, tx included in block INVOKE_CONTRACT = 0; // query a pre-created contract, tx not included in block QUERY_CONTRACT = 1; // subscribe block info,tx info and contract info. tx not included in block SUBSCRIBE = 2; // archive/restore block, tx not included in block ARCHIVE = 3; } // a k-v pair message KeyValuePair { string key = 1; bytes value = 2; } ``` * ChainId锛氶摼鏍囪瘑锛岃〃鏄庢湰浜ゆ槗鏄拡瀵瑰摢鏉¢摼鐨勶紝闃叉涓€涓氦鏄撳湪澶氫釜閾句腑琚墦鍖� * TxType锛氫氦鏄撶被鍨嬶紝鐩墠鏈�4绉嶏紝鍚堢害璋冪敤銆佸悎绾︽煡璇€€佽闃呫€佸綊妗c€傚叾涓彧鏈夊悎绾﹁皟鐢ㄤ細琚墦鍖呬笂閾撅紝鍙﹀鍑犵鍙敤浜嶴DK涓庤妭鐐逛箣闂寸殑閫氫俊鍗忚 * TxId锛氫氦鏄揑D锛岀敤鍋氳浜ゆ槗鐨勫叏灞€鍞竴鎬ф爣璇� * Timestamp锛氱敓鎴愪氦鏄撶殑unix鏃堕棿鎴筹紝褰損roposer浠庝氦鏄撴睜鑾峰彇浜ゆ槗鏃讹紝鐢ㄦ潵妫€娴嬭浜ゆ槗鏄惁瓒呮椂鏈笂閾撅紱濡傛灉瓒呮椂锛岃浜ゆ槗灏嗕粠浜ゆ槗姹犲垹闄� * ExpirationTime锛氫氦鏄撶殑鍒版湡鐨剈nix鏃堕棿锛屽崟浣嶇锛屼笉涓�0鏃讹紝浜ゆ槗蹇呴』鍦ㄨ鏃堕棿鎴充箣鍓嶈鎵撳寘涓婇摼 * ContractName锛氳璋冪敤鐨勫悎绾﹀悕 * Method锛氳璋冪敤鐨勫悎绾︽柟娉曞悕 * Parameters锛氳皟鐢ㄥ悎绾︽柟娉曟椂浼犲叆鐨勫弬鏁板垪琛紝涓篕ey/Value鍒楄〃绫诲瀷 * Sequence锛氫氦鏄撶殑椤哄簭鍙凤紝0琛ㄧず璇ヤ氦鏄撴病鏈夐『搴忚姹傦紱澶т簬0鍒欐寜浜ゆ槗鍙戣捣浜洪『搴忛€掑 * Limit锛氫氦鏄撴墽琛岀殑闄愬埗锛屽浜庢湁Gas闄愬埗鐨勫満鏅紝鍙互鏄疓asLimit+GasPrice锛屽浜庢湁瓒呮椂闄愬埗鐨勫満鏅紝鍙互鏄疶imeout姣鏁� #### 浜ゆ槗鍙戦€佽€呬笌绛惧悕 ``` // endorsement info, including a signer and his signature message EndorsementEntry { // signer accesscontrol.Member signer = 1; // signature bytes signature = 2; } // member of blockchain message Member { // organization identifier of the member string org_id = 1; // member type MemberType member_type = 2; // member identity related info bytes bytes member_info = 3; } enum MemberType { //X509 cert CERT = 0; //cert hash CERT_HASH = 1; //public key PUBLIC_KEY = 2; //did DID = 3; //alias ALIAS = 4; //address ADDR = 5; } ``` * Sender锛氫氦鏄撳彂閫佽€呬俊鎭紝鐢盨igner鍜孲ignature缁勬垚 * Signer涓篗ember绫诲瀷锛屼富瑕佸寘鍚互涓嬩俊鎭細 * OrgId锛氭垚鍛樻墍灞炴満鏋勭紪鍙� * MemberType锛氭垚鍛樼殑绫诲瀷锛屼富瑕佹湁锛歑509璇佷功銆佽瘉涔﹀搱甯屻€佸叕閽ャ€丏ID銆佸埆鍚嶃€佸湴鍧€绛夊嚑绉嶇被鍨嬨€� * MemberInfo锛氭垚鍛樼殑韬唤淇℃伅锛屽彲浠ユ槸璇佷功淇℃伅涔熷彲浠ユ槸璇佷功鍝堝笇锛屾垨鑰呮槸鍏挜銆丏ID銆佸埆鍚嶃€佸湴鍧€绛夛紝渚濊禆浜嶮emberType瀛楁 * Signature锛氫氦鏄撳彂閫佽€呭Payload鐨勭鍚嶏紝鍏蜂綋绛惧悕绠楁硶鍙栧喅涓庨摼閰嶇疆鍜孹509璇佷功涓殑绛惧悕绠楁硶 #### 浜ゆ槗缁撴灉 ```go // tx result, part of a transaction in block message Result { // response code TxStatusCode code = 1; // returned data, set in smart contract ContractResult contract_result = 2; // hash of the transaction's read-write set bytes rw_set_hash = 3; string message = 4; } // invoke user contract method return UserContractReturnPayload // Unmarshal from TransactResult.TxResponse.payload message ContractResult { // user contract defined return code, 0-ok, >0 user define error code. for example, insufficient balance in token transfer uint32 code = 1; // user contract defined result bytes result = 2; // user contract defined result message string message = 3; // gas used by current contract(include contract call) uint64 gas_used = 4; // contract events repeated ContractEvent contract_event = 5; } // contract event saved in block chain message ContractEvent { string topic = 1; string tx_id = 2; string contract_name = 3; string contract_version = 4; repeated string event_data = 5; } ``` * TxStatusCode锛氫氦鏄撴墽琛岀粨鏋滅殑鐘舵€� * ContractResult锛氬悎绾︽墽琛岀粨鏋� * Code锛氱敤鎴疯嚜瀹氫箟鐨勫悎绾︽墽琛岀粨鏋滅殑鐘舵€侊紝0琛ㄧず鎴愬姛锛岄潪0琛ㄧず寮傚父 * Result锛氬悎绾︽墽琛岃繑鍥炵殑缁撴灉 * Message锛氬悎绾︽墽琛岃繑鍥炵殑閿欒淇℃伅 * GasUsed锛氬悎绾︽墽琛屾秷鑰楃殑Gas鏁伴噺 * ContractEvent锛氬悎绾︽墽琛屼骇鐢熺殑浜嬩欢鏃ュ織 * RwSetHash锛氫氦鏄撴墽琛岀粨鏋滅殑璇诲啓闆嗗搱甯� * Message锛氬悎绾﹀杩斿洖鐨勯敊璇俊鎭� ### 浜ゆ槗璇锋眰缁撴瀯 ```go // transaction request proposed by user message TxRequest { // payload Payload payload = 1; // sender account and sender's signature EndorsementEntry sender = 2; // endorsers account and signatures repeated EndorsementEntry endorsers = 3; } ``` 鐢ㄦ埛鍙戣捣涓€涓氦鏄撹姹傜殑瀹屾暣缁撴瀯锛屽寘鎷細 * Payload锛氫氦鏄撶殑杞借嵎鏁版嵁锛屼氦鏄撶殑鏍稿績淇℃伅 * Sender锛氫氦鏄撶殑鍙戣捣鑰呬俊鎭拰鍙戣捣鑰呭Payload鐨勭鍚嶄俊鎭� * Endorsers锛氬绛炬儏鍐典笅锛屽涓儗涔︿汉鐨勮韩浠戒俊鎭拰鍏跺Payload鐨勭鍚嶄俊鎭� ### 浜ゆ槗鍝嶅簲缁撴瀯 ```go // tx request - tx response, only for RPC response message TxResponse { // response code TxStatusCode code = 1; // response message string message = 2; // returned data, set in smart contract ContractResult contract_result = 3; // tx id of request string tx_id = 4; // async tx mode: tx timestamp is zero // sync tx mode: tx timestamp is TxRequest.Payload.Timestamp int64 tx_timestamp = 5; // async tx mode: tx block height is zero // sync tx mode: tx block height is the height of block which this tx was packaged uint64 tx_block_height = 6; } ``` * Code锛氫氦鏄撴墽琛岀粨鏋滅殑鐘舵€� * Message锛氫氦鏄撻敊璇俊鎭� * ContractResult锛氬悎绾︽墽琛岀粨鏋� * TxId锛氬搴旂殑浜ゆ槗ID * TxTimestamp锛� 鍒涘缓浜ゆ槗鐨勬椂闂存埑 * tx_block_height锛� 鍖哄潡楂樺害 ### 浜ゆ槗鎵ц缁撴灉鐨勮鍐欓泦 #### 璇诲啓闆� ```go // TxRWSet describes all the operations of a transaction on ledger message TxRWSet { // transaction identifier string tx_id = 1; // read set repeated TxRead tx_reads = 2; // write set repeated TxWrite tx_writes = 3; } ``` 璇诲啓闆嗕负浜ゆ槗鍚堢害姝e父鎵ц鍚庡鍏朵笘鐣岀姸鎬佺殑鏀瑰彉鎯呭喌鐨勫弽搴旓紝涓昏鍖呮嫭锛� * TxId 鏈鍐欓泦鏄敱鍝釜浜ゆ槗浜х敓鐨� * TxRead 璇婚泦鍒楄〃 * TxWrite 鍐欓泦鍒楄〃 #### 璇诲璞� 璇婚泦涓昏鐢ㄤ簬鍦ㄥ苟鍙戞墽琛屽悎绾︿氦鏄撳悗鍒ゆ柇骞跺彂鐨勪氦鏄撲箣闂存槸鍚﹀瓨鍦ㄦ暟鎹紙鐗堟湰锛夊啿绐侊紝濡傛灉鍐茬獊鍒欓渶瑕佸湪DAG缁撴瀯涓弽鏄犱氦鏄撲箣闂寸殑渚濊禆鎯呭喌锛屽苟璋冩暣鍐茬獊浜ゆ槗鐨勬墽琛岄『搴忥紝閲嶆柊鎵ц鍚堢害銆� ```go // TxRead describes a read operation on a key message TxRead { // read key bytes key = 1; // the value of the key bytes value = 2; // contract name, used in cross-contract calls // set to null if only the contract in transaction request is called string contract_name = 3; // read key version KeyVersion version = 4; } ``` 涓€鏉′氦鏄撹涓昏鍖呮嫭锛� * ContractName 鏈璁板綍鏄鐨勫摢涓悎绾︾殑鐘舵€佹暟鎹� * Key 鏈褰曡鍙栫殑鐘舵€侀敭鍊间俊鎭� * Version 璇诲彇鍒扮殑鐗堟湰 * Value 璇诲彇鍒扮殑鍊硷紝鍚庢湡鑰冭檻灏哣alue绉婚櫎锛屽彧闇€瑕佷緷闈燰ersion鍗冲彲杩涜鍐茬獊鍒ゆ柇銆� #### 鍐欏璞� 浜ゆ槗姝e父鎵ц瀹屾瘯鍚庯紝濡傛灉涓栫晫鐘舵€佸彂鐢熶簡鏇存敼锛岄偅涔堝啓闆嗗氨浼氳褰曡缁嗙殑鏇存敼璁板綍銆� ```go // TxRead describes a write/delete operation on a key message TxWrite { // write key bytes key = 1; // write value bytes value = 2; // contract name, used in cross-contract calls // set to null if only the contract in transaction request is called string contract_name = 3; } ``` 浜ゆ槗鍐欏寘鎷互涓嬪唴瀹癸細 * ContractName 瀵瑰摢涓悎绾︾殑鐘舵€佹暟鎹繘琛屼簡鏇存敼 * Key 琚慨鏀圭殑鐘舵€侀敭鍊� * Value 淇敼鍚庣殑鐘舵€佸€� <br><br>