8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/apidoc/fabric_contract/prelude/sidebar-items.js:
--------------------------------------------------------------------------------
1 | initSidebarItems({"fn":[["handle_wapc","Map to the ContractService"],["host_call","The function through which all host calls take place."],["host_log",""]],"macro":[["wapc_handler",""]],"struct":[["ContractDefn","Internal definition of a contract"],["TransactionFn",""],["TransactionFnBuilder",""]],"type":[["CallResult",""],["Result","WaPC Guest SDK result type"]]});
--------------------------------------------------------------------------------
/docs/apidoc/contract_macros/sidebar-items.js:
--------------------------------------------------------------------------------
1 | initSidebarItems({"attr":[["contract_impl","Use this macro to mark the implementation of the your contract structure"],["property","Define the properties of the datatype"],["transaction","Use this to mark the functions that are considered to be transaction functions"]],"derive":[["DataTypeMacro","Use this to mark the structs that serve as complex data types Need to provide example"]]});
--------------------------------------------------------------------------------
/docs/apidoc/fabric_contract/macro.launch_handler!.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/fabric_contract_macros/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "fabric_contract_macros"
3 | description = "Hyperledger Fabric Contract API in Rust"
4 | version = "0.1.3"
5 | edition = "2018"
6 | autotests = false
7 | authors = ["Hyperledger Fabric Developers"]
8 | repository = "https://github.com/hyperledgendary/fabric-contract-api-rust"
9 | license = "Apache-2.0"
10 | documentation = "https://hyperledgendary.github.io/fabric-contract-api-rust/"
11 | readme = "README.md"
12 |
13 | [lib]
14 | proc-macro = true
15 |
16 | [dependencies]
17 | syn = { version = "1.0.27", features = ["extra-traits","full"] }
18 | quote = "1.0.6"
19 | proc-macro2 = "1.0.17"
20 |
--------------------------------------------------------------------------------
/tests/assets/chaincode.env:
--------------------------------------------------------------------------------
1 | # CHAINCODE_SERVER_ADDRESS must be set to the host and port where the peer can
2 | # connect to the chaincode server
3 | CHAINCODE_SERVER_ADDRESS=wasmcc.example.com:9999
4 |
5 | # CHAINCODE_ID must be set to the Package ID that is assigned to the chaincode
6 | # on install. The `peer lifecycle chaincode queryinstalled` command can be
7 | # used to get the ID after install if required
8 | CHAINCODE_ID=wasmftw:eeae07c6e9455f329e28f9a0eed977ae3549be68e68247018f71dc5a5f511c0d
9 |
10 | # CHAINCODE_WASM_FILE must be set to the fully qualified pathname of the Wasm
11 | # chaincode
12 | CHAINCODE_WASM_FILE=/local/basic_contract_rs.wasm
13 |
--------------------------------------------------------------------------------
/basic_contract_rs/src/lib.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | //! A basic Smart Contract
6 | //!
7 | //! Implements Creation, and Retrieval of a simple asset
8 | //!
9 |
10 | mod contracts;
11 | pub use crate::contracts::AssetContract;
12 |
13 | mod types;
14 | pub use crate::types::MyAsset;
15 |
16 | // The macro to indicate the function that will be used to register the contracts.
17 | // if there is more than one, use a comma separated list
18 | //
19 | // Provide the function that will create a new instance of the contract strcut
20 | // More than one contract struct can be provided.
21 | fabric_contract::register!(AssetContract::new);
22 |
--------------------------------------------------------------------------------
/fabric_contract/src/dataapi/serializer.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | use super::typeschema::ContractType::*;
5 | use super::TypeSchema;
6 | pub trait Converter {
7 | fn into_string(&self, buffer: &[u8], ts: &TypeSchema) -> String;
8 | }
9 |
10 | #[derive(Debug, Clone, Copy)]
11 | pub struct JSONConverter {}
12 |
13 | impl Converter for JSONConverter {
14 | // straight conversion
15 | fn into_string(&self, buffer: &[u8], ts: &TypeSchema) -> String {
16 | match ts.contract_type {
17 | CTString => String::from_utf8(buffer.to_vec()).unwrap(),
18 | _ => "".to_string(),
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/docs/apidoc/implementors/core/iter/traits/collect/trait.IntoIterator.js:
--------------------------------------------------------------------------------
1 | (function() {var implementors = {};
2 | implementors["fabric_contract"] = [{"text":"impl IntoIterator for StateQueryList","synthetic":false,"types":["fabric_contract::ledgerapi::statequerylist::StateQueryList"]}];
3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})()
--------------------------------------------------------------------------------
/basic_contract_rs/README.md:
--------------------------------------------------------------------------------
1 | # basic_contract_rs
2 |
3 | To create a basic Smart Contract.
4 |
5 | - Create a Rust library crate
6 | - add the following dependencies
7 |
8 | ```
9 | fabric_contract = { path = "../fabric_contract" }
10 | log = "0.4.8"
11 | wapc-guest = "0.3.1"
12 | ```
13 |
14 | - In the lib.rs of the your crate, register the contracts that will be required, by passing the a function that will create a new instance of the contract.
15 |
16 | ```rust
17 | fabric_contract::register!( AssetContract::new );
18 | ```
19 |
20 | - All contracts must implement the Contract trait
21 | - The `#[Contract_Impl]` and `#[Transaction()]` macros should be used on the contract implementation, and the transaction functions
22 | - Compile to Wasm
--------------------------------------------------------------------------------
/docs/apidoc/fabric_contract/sidebar-items.js:
--------------------------------------------------------------------------------
1 | initSidebarItems({"attr":[["contract_impl","Use this macro to mark the implementation of the your contract structure"],["property","Define the properties of the datatype"],["transaction","Use this to mark the functions that are considered to be transaction functions"]],"derive":[["DataTypeMacro","Use this to mark the structs that serve as complex data types Need to provide example"]],"macro":[["register","Macro to use in the lib.rs file of your contract's crate"]],"mod":[["blockchain","Module to provide APIs to get information about Fabric"],["contract","Module to provide APIs to write contracts and interact with the ledger"],["data","Module to use to define the complex datatypes"],["prelude",""],["runtime","Module to provide 'runtime' services."]]});
--------------------------------------------------------------------------------
/fabric_contract/src/ledgerapi/endorsement.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | /// The ROLE definition
6 | #[derive(Debug, Clone)]
7 | pub enum ROLE {
8 | MEMBER,
9 | PEER,
10 | ADMIN,
11 | CLIENT,
12 | }
13 |
14 | /// The Expressions - either AND, OR, OUTOF or the actual Principal
15 | #[derive(Debug, Clone)]
16 | pub enum Expression {
17 | AND(Vec),
18 | OR(Vec),
19 | OUTOF(Vec, usize),
20 | Principal(String, ROLE),
21 | }
22 |
23 | /// Struct to represent the Overal Endorsement
24 | #[derive(Debug)]
25 | pub struct StateBasedEndorsement {
26 | pub root: Expression,
27 | }
28 |
29 | impl StateBasedEndorsement {
30 | pub fn build(expr: Expression) -> Self {
31 | StateBasedEndorsement { root: expr }
32 | }
33 | }
--------------------------------------------------------------------------------
/fabric_contract/README.md:
--------------------------------------------------------------------------------
1 | # fabric_contract_macros
2 |
3 | This is the the library crate for...
4 |
5 | # Fabric Rust Contract-API
6 |
7 | "The Fabric Contract API in rust, with Wasm as the compilation target."
8 |
9 | A SmartContract is single crate, containing one or more contract sructs, compiled to a Wasm library. In this repo the `basic_contract_rs` is an example. This is a simple asset based contract based on the standard vs code extension examples.
10 |
11 | [End-to-End Getting Started Guide](https://hyperledgendary.github.io/fabric-contract-api-rust/guides/getting-started.html)
12 |
13 | [Check the API Documentation for fabric_contract](https://hyperledgendary.github.io/fabric-contract-api-rust/apidoc/fabric_contract/index.html)
14 |
15 | [Full Documentation](https://hyperledgendary.github.io/fabric-contract-api-rust/)
16 |
--------------------------------------------------------------------------------
/fabric_contract_macros/README.md:
--------------------------------------------------------------------------------
1 | # fabric_contract_macros
2 |
3 | This is the the macros crate for...
4 |
5 | # Fabric Rust Contract-API
6 |
7 | "The Fabric Contract API in rust, with Wasm as the compilation target."
8 |
9 | A SmartContract is single crate, containing one or more contract sructs, compiled to a Wasm library. In this repo the `basic_contract_rs` is an example. This is a simple asset based contract based on the standard vs code extension examples.
10 |
11 | [End-to-End Getting Started Guide](https://hyperledgendary.github.io/fabric-contract-api-rust/guides/getting-started.html)
12 |
13 | [Check the API Documentation for fabric_contract](https://hyperledgendary.github.io/fabric-contract-api-rust/apidoc/fabric_contract/index.html)
14 |
15 | [Full Documentation](https://hyperledgendary.github.io/fabric-contract-api-rust/)
16 |
--------------------------------------------------------------------------------
/docs/apidoc/implementors/core/iter/traits/collect/trait.FromIterator.js:
--------------------------------------------------------------------------------
1 | (function() {var implementors = {};
2 | implementors["fabric_contract"] = [{"text":"impl FromIterator<State> for StateQueryList","synthetic":false,"types":["fabric_contract::ledgerapi::statequerylist::StateQueryList"]}];
3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})()
--------------------------------------------------------------------------------
/asset_transfer_secure_private_rs/src/lib.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | //! Main library module
6 | //!
7 | //! The purpose of this is to do register the contracts.
8 | //!
9 | //! Other setup can take place here but do so with
10 | //! caution. Any failure will terminate the container
11 | //! and there is limited scope for logging at stage in
12 | //! the lifecyle
13 | mod contracts;
14 | pub use crate::contracts::AssetTransfer;
15 |
16 |
17 | mod types;
18 | pub use crate::types::{AssetPrivate, Asset, PriceAgreement};
19 |
20 | // The macro to indicate the function that will be used to register the contracts.
21 | // if there is more than one, use a comma separated list
22 | //
23 | // Provide the function that will create a new instance of the contract strcut
24 | // More than one contract struct can be provided.
25 | fabric_contract::register!( AssetTransfer::new );
--------------------------------------------------------------------------------
/asset_transfer_rs/src/lib.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | //! Main library module
6 | //!
7 | //! The purpose of this is to do register the contracts.
8 | //!
9 | //! Other setup can take place here but do so with
10 | //! caution. Any failure will terminate the container
11 | //! and there is limited scope for logging at stage in
12 | //! the lifecyle
13 | mod contracts;
14 | pub use crate::contracts::AssetTransfer;
15 | pub use crate::contracts::AssetTransferQuery;
16 |
17 | mod types;
18 | pub use crate::types::Asset;
19 |
20 | // The macro to indicate the function that will be used to register the contracts.
21 | // if there is more than one, use a comma separated list
22 | //, AssetTransferQuery::new
23 | // Provide the function that will create a new instance of the contract strcut
24 | // More than one contract struct can be provided.
25 | fabric_contract::register!( AssetTransfer::new );
--------------------------------------------------------------------------------
/docs/apidoc/settings.css:
--------------------------------------------------------------------------------
1 | .setting-line{padding:5px;position:relative;}.setting-line>div{max-width:calc(100% - 74px);display:inline-block;vertical-align:top;font-size:17px;padding-top:2px;}.setting-line>.title{font-size:19px;width:100%;max-width:none;border-bottom:1px solid;}.toggle{position:relative;display:inline-block;width:45px;height:27px;margin-right:20px;}.toggle input{display:none;}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.3s;transition:.3s;}.slider:before{position:absolute;content:"";height:19px;width:19px;left:4px;bottom:4px;background-color:white;-webkit-transition:.3s;transition:.3s;}input:checked+.slider{background-color:#2196F3;}input:focus+.slider{box-shadow:0 0 1px #2196F3;}input:checked+.slider:before{-webkit-transform:translateX(19px);-ms-transform:translateX(19px);transform:translateX(19px);}.setting-line>.sub-settings{padding-left:42px;width:100%;display:block;}
--------------------------------------------------------------------------------
/docs/apidoc/implementors/std/error/trait.Error.js:
--------------------------------------------------------------------------------
1 | (function() {var implementors = {};
2 | implementors["fabric_contract"] = [{"text":"impl Error for ContractError","synthetic":false,"types":["fabric_contract::error::ContractError"]},{"text":"impl Error for LedgerError","synthetic":false,"types":["fabric_contract::error::LedgerError"]}];
3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})()
--------------------------------------------------------------------------------
/fabric_contract/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "fabric_contract"
3 | description = "Hyperledger Fabric Contract API in Rust"
4 | version = "0.1.3"
5 | authors = ["Hyperledger Fabric Developers"]
6 | edition = "2018"
7 | repository = "https://github.com/hyperledgendary/fabric-contract-api-rust"
8 | license = "Apache-2.0"
9 | documentation = "https://hyperledgendary.github.io/fabric-contract-api-rust/"
10 | readme = "README.md"
11 |
12 | [lib]
13 | #crate-type = ["cdylib"]
14 |
15 | [profile.release]
16 | # Optimize for small code size
17 | opt-level = "s"
18 |
19 | [dependencies]
20 | wapc-guest = "0.3.1"
21 | #fabric_contract_macros = { version = "0.1.3" }
22 | fabric_contract_macros = { path = "../fabric_contract_macros" }
23 | fabric_ledger_protos = "0.7.0"
24 | log = "0.4.8"
25 | protobuf = "2.14.0"
26 | # protobuf handling
27 | prost = "0.6.1"
28 | lazy_static = "1.4.0"
29 |
30 | [dev-dependencies]
31 | wasm-bindgen-test = "0.2"
32 | mockall = "0.7.2"
33 | claim = "0.3"
34 |
35 | [build-dependencies]
36 | prost-build = { version = "0.6.1" }
37 |
--------------------------------------------------------------------------------
/docs/apidoc/implementors/prost/message/trait.Message.js:
--------------------------------------------------------------------------------
1 | (function() {var implementors = {};
2 | implementors["fabric_contract"] = [{"text":"impl Message for Arguments","synthetic":false,"types":["fabric_contract::runtime::runtime::items::Arguments"]},{"text":"impl Message for Return","synthetic":false,"types":["fabric_contract::runtime::runtime::items::Return"]}];
3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})()
--------------------------------------------------------------------------------
/fabric_contract/src/blockchainapi/clientidentity.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | #![allow(dead_code)]
5 | /// Represents the identity that is requesting this transaction
6 | ///
7 | pub struct ClientIdentity {}
8 |
9 | impl ClientIdentity {
10 | fn new() -> ClientIdentity {
11 | ClientIdentity {}
12 | }
13 |
14 | /// The String id associated with this identiy
15 | pub fn get_id(&self) -> String {
16 | todo!("get_id");
17 | }
18 |
19 | /// The MSP Identifier of this identity
20 | ///
21 | pub fn get_mspid(&self) -> String {
22 | todo!("get_mspid")
23 | }
24 |
25 | /// Returns the value of the client's attribute named `attrName`.
26 | ///
27 | pub fn get_attribute(&self, attr_name: String) -> Option {
28 | todo!("get_attributed")
29 | }
30 |
31 | // GetX509Certificate returns the X509 certificate associated with the client,
32 | // or nil if it was not identified by an X509 certificate.
33 | // GetX509Certificate() (*x509.Certificate, error)
34 | }
35 |
--------------------------------------------------------------------------------
/docs/apidoc/LICENSE-MIT.txt:
--------------------------------------------------------------------------------
1 | Permission is hereby granted, free of charge, to any
2 | person obtaining a copy of this software and associated
3 | documentation files (the "Software"), to deal in the
4 | Software without restriction, including without
5 | limitation the rights to use, copy, modify, merge,
6 | publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software
8 | is furnished to do so, subject to the following
9 | conditions:
10 |
11 | The above copyright notice and this permission notice
12 | shall be included in all copies or substantial portions
13 | of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
--------------------------------------------------------------------------------
/docs/apidoc/implementors/core/marker/trait.StructuralPartialEq.js:
--------------------------------------------------------------------------------
1 | (function() {var implementors = {};
2 | implementors["fabric_contract"] = [{"text":"impl StructuralPartialEq for Arguments","synthetic":false,"types":["fabric_contract::runtime::runtime::items::Arguments"]},{"text":"impl StructuralPartialEq for Return","synthetic":false,"types":["fabric_contract::runtime::runtime::items::Return"]}];
3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})()
--------------------------------------------------------------------------------
/docs/apidoc/theme.js:
--------------------------------------------------------------------------------
1 | var themes=document.getElementById("theme-choices");var themePicker=document.getElementById("theme-picker");function showThemeButtonState(){themes.style.display="block";themePicker.style.borderBottomRightRadius="0";themePicker.style.borderBottomLeftRadius="0"}function hideThemeButtonState(){themes.style.display="none";themePicker.style.borderBottomRightRadius="3px";themePicker.style.borderBottomLeftRadius="3px"}function switchThemeButtonState(){if(themes.style.display==="block"){hideThemeButtonState()}else{showThemeButtonState()}};function handleThemeButtonsBlur(e){var active=document.activeElement;var related=e.relatedTarget;if(active.id!=="themePicker"&&(!active.parentNode||active.parentNode.id!=="theme-choices")&&(!related||(related.id!=="themePicker"&&(!related.parentNode||related.parentNode.id!=="theme-choices")))){hideThemeButtonState()}}themePicker.onclick=switchThemeButtonState;themePicker.onblur=handleThemeButtonsBlur;["dark","light"].forEach(function(item){var but=document.createElement('button');but.textContent=item;but.onclick=function(el){switchTheme(currentTheme,mainTheme,item,true)};but.onblur=handleThemeButtonsBlur;themes.appendChild(but)})
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | # Starter pipeline
2 | # Start with a minimal pipeline that you can customize to build and deploy your code.
3 | # Add steps that build, run tests, deploy, and more:
4 | # https://aka.ms/yaml
5 |
6 | trigger:
7 | - master
8 |
9 | pool:
10 | vmImage: 'ubuntu-latest'
11 |
12 | jobs:
13 | - job: Clippy
14 | container: 'rust:latest'
15 | steps:
16 | - script: rustup component add clippy
17 | displayName: Install Clippy
18 | - script: cargo clippy --all-targets --all-features
19 | displayName: Run clippy
20 |
21 | - job: BuildUT
22 | displayName: 'Generate Rust lib'
23 | steps:
24 | - script: |
25 | curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain default
26 | echo "##vso[task.prependpath]$HOME/.cargo/bin"
27 | rustup target add wasm32-unknown-unknown
28 | displayName: 'Install rust'
29 |
30 | - script: cargo build --all --target wasm32-unknown-unknown
31 | displayName: Cargo build
32 |
33 | - script: cargo test --all
34 | displayName: Cargo test
35 |
36 | - task: NodeTool@0
37 | inputs:
38 | versionSpec: '12.x'
39 | checkLatest: true
40 |
41 | - script: |
42 | ./tests/setup.sh
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/docs/_includes/header.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/asset_transfer_secure_private_rs/src/types/price_agreement.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | use fabric_contract::contract::*;
5 | use fabric_contract::data::*;
6 | use serde::{Deserialize, Serialize};
7 | use std::str::from_utf8;
8 |
9 | // Use the log crate to support logging
10 | use log::{debug};
11 |
12 |
13 | #[derive(Serialize, Deserialize, Debug, Default)]
14 | pub struct PriceAgreement {
15 | id: String,
16 | price: u32
17 | }
18 |
19 | impl PriceAgreement {
20 | pub fn new(id: String, price: u32) -> PriceAgreement {
21 | PriceAgreement {
22 | id,
23 | price
24 | }
25 | }
26 | }
27 |
28 | /// Very important to implement the DataType Trait for the Asset
29 | ///
30 | /// This provides the ability to store the data in the ledger
31 | impl DataType for PriceAgreement {
32 | fn to_state(&self) -> State {
33 | let json = serde_json::to_string(self).unwrap();
34 | debug!("ToState::{}",&json.as_str());
35 | let buffer = json.into_bytes();
36 | State::from((self.id.clone(), buffer))
37 | }
38 |
39 | fn get_key(&self) -> String {
40 | PriceAgreement::form_key(&self.id)
41 |
42 | }
43 |
44 | fn build_from_state(state: State) -> Self {
45 | let b = state.value();
46 |
47 | let str = match from_utf8(&b) {
48 | Ok(a) => a,
49 | Err(_) => panic!("Err"),
50 | };
51 | debug!("build_from_state:: {}",&str);
52 | serde_json::from_str(str).unwrap()
53 | }
54 |
55 |
56 | fn form_key(k: &String) -> String {
57 | format!("PriceAgreement#{}",k)
58 | }
59 | }
60 |
61 | impl WireBufferFromReturnType for WireBuffer {
62 | fn from_rt(self: &mut Self, s: PriceAgreement) {
63 | // we've got a wire buffer object and we need to set the bytes here from the string
64 | let json = serde_json::to_string(&s).unwrap();
65 | debug!("wire buffer returning the value {}",json.as_str());
66 | let buffer = json.into_bytes();
67 | self.buffer = Some(buffer);
68 | }
69 | }
70 |
71 | impl From<&WireBuffer> for PriceAgreement {
72 | fn from(wb: &WireBuffer) -> Self {
73 | match &wb.buffer {
74 | Some(buffer) => {
75 | match std::str::from_utf8(&buffer) {
76 | Ok(a) => serde_json::from_str(a).unwrap(),
77 | _ => unreachable!(),
78 | }
79 | }
80 | None => panic!(),
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/asset_transfer_secure_private_rs/src/types/trade_agreement.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | use fabric_contract::contract::*;
5 | use fabric_contract::data::*;
6 | use serde::{Deserialize, Serialize};
7 | use std::str::from_utf8;
8 |
9 | // Use the log crate to support logging
10 | use log::debug;
11 |
12 | #[derive(Serialize, Deserialize, Debug, Default)]
13 | pub struct TradeAgreement {
14 | id: String,
15 | price: u32,
16 | trade_id: String,
17 | }
18 |
19 | impl TradeAgreement {
20 | pub fn new(id: String, price: u32, trade_id: String) -> TradeAgreement {
21 | TradeAgreement {
22 | id,
23 | price,
24 | trade_id,
25 | }
26 | }
27 | }
28 |
29 | /// Very important to implement the DataType Trait for the Asset
30 | ///
31 | /// This provides the ability to store the data in the ledger
32 | impl DataType for TradeAgreement {
33 | fn to_state(&self) -> State {
34 | let json = serde_json::to_string(self).unwrap();
35 | debug!("ToState::{}", &json.as_str());
36 | let buffer = json.into_bytes();
37 | State::from((self.id.clone(), buffer))
38 | }
39 |
40 | fn get_key(&self) -> String {
41 | TradeAgreement::form_key(&self.id)
42 | }
43 |
44 | fn build_from_state(state: State) -> Self {
45 | let b = state.value();
46 |
47 | let str = match from_utf8(&b) {
48 | Ok(a) => a,
49 | Err(_) => panic!("Err"),
50 | };
51 | debug!("build_from_state:: {}", &str);
52 | serde_json::from_str(str).unwrap()
53 | }
54 |
55 | fn form_key(k: &String) -> String {
56 | format!("TradeAgreement#{}",k)
57 | }
58 | }
59 |
60 | impl WireBufferFromReturnType for WireBuffer {
61 | fn from_rt(self: &mut Self, s: TradeAgreement) {
62 | // we've got a wire buffer object and we need to set the bytes here from the string
63 | let json = serde_json::to_string(&s).unwrap();
64 | debug!("wire buffer returning the value {}", json.as_str());
65 | let buffer = json.into_bytes();
66 | self.buffer = Some(buffer);
67 | }
68 | }
69 |
70 | impl From<&WireBuffer> for TradeAgreement {
71 | fn from(wb: &WireBuffer) -> Self {
72 | match &wb.buffer {
73 | Some(buffer) => match std::str::from_utf8(&buffer) {
74 | Ok(a) => serde_json::from_str(a).unwrap(),
75 | _ => unreachable!(),
76 | },
77 | None => panic!(),
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 | title: Rust Smart Contract API
4 | ---
5 |
6 | This **Technology Preview** provides an updated Contract and Ledger API in Rust. It is targetted to be compiled to WebAssembly and run in the `fabric-chaincode-wasm` engine.
7 |
8 | The API presented here is the evolution of the APIs available in the other SDKs to support developing smart contracts (chaincode). There are three other smart contract SDKs available for Go, Node.js, and Java SDK:
9 |
10 | * [Go SDK documentation](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim)
11 | * [Node.js SDK documentation](https://hyperledger.github.io/fabric-chaincode-node/)
12 | * [Java documentation](https://hyperledger.github.io/fabric-chaincode-java/)
13 |
14 | ## Getting setup
15 |
16 | You'll need some tools installed, some you might already have:
17 |
18 | - [docker](https://docs.docker.com/get-docker/) & [docker-compose](https://docs.docker.com/compose/install/)
19 | - rust and the Wasm toolchain
20 | - Stable Rust is sufficient, nightly is not required. Instructions at the [rust-lang.org](https://www.rust-lang.org/tools/install)
21 | - To build a Wasm binary you will need to have the wasm target. Note that wasm-pack is not required here as there is no JavaScript host.
22 | - `rustup target add wasm32-unknown-unknown`
23 | - [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
24 | - [just](https://github.com/casey/just) for use as a script running tool
25 |
26 | [VSCode](https://code.visualstudio.com/download) is our preferred editor, with the [Rust Extension](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust) using the [Rust Analyser](https://github.com/rust-analyzer/rust-analyzer). You may, of course, have your own favourite editor.
27 |
28 | This also has been developed on Linux; but development should be possible on other platforms.
29 |
30 | ## Guides
31 |
32 | Essential reading, each guide around a single topic.
33 |
34 | - [API Documentation](./apidoc/fabric_contract/index.html)
35 | {% for doc in site.pages %} {% if doc.category =='guides' %}
36 | - [{{ doc.title }}]({{site.baseurl}}{{ doc.url }})
37 | {% endif %}
38 | {% endfor %}
39 |
40 | ## Samples
41 |
42 | Two examples are available in this repo.
43 |
44 | - [Basic Asset Transfer](https://github.com/hyperledgendary/fabric-contract-api-rust/tree/master/basic_contract_rs)
45 | - [Secure Asset Transfer](https://github.com/hyperledgendary/fabric-contract-api-rust/tree/master/asset_transfer_rs)
46 |
47 | Note that 'Secure Asset Transfer' is a work in progress and will not yet compile
48 |
--------------------------------------------------------------------------------
/asset_transfer_secure_private_rs/src/types/asset_private.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | use fabric_contract::contract::*;
5 | use fabric_contract::data::*;
6 | use serde::{Deserialize, Serialize};
7 | use std::str::from_utf8;
8 |
9 | // Use the log crate to support logging
10 | use log::{debug};
11 |
12 | ///
13 |
14 | #[derive(Serialize, Deserialize, Debug, Default)]
15 | pub struct AssetPrivate {
16 | id: String,
17 | appraised_value: u32,
18 | itemcode: String,
19 | description: String
20 | }
21 |
22 | impl AssetPrivate {
23 | pub fn new(id: String, appraised_value: u32, itemcode:String, description: String) -> AssetPrivate {
24 | AssetPrivate {
25 | id,
26 | appraised_value,
27 | itemcode,
28 | description
29 | }
30 | }
31 | }
32 |
33 | /// Very important to implement the DataType Trait for the Asset
34 | ///
35 | /// This provides the ability to store the data in the ledger
36 | impl DataType for AssetPrivate {
37 | fn to_state(&self) -> State {
38 | let json = serde_json::to_string(self).unwrap();
39 | debug!("ToState::{}",&json.as_str());
40 | let buffer = json.into_bytes();
41 | State::from((self.id.clone(), buffer))
42 | }
43 |
44 | fn get_key(&self) -> String {
45 | self.id.clone()
46 | }
47 |
48 | fn build_from_state(state: State) -> Self {
49 | let b = state.value();
50 |
51 | let str = match from_utf8(&b) {
52 | Ok(a) => a,
53 | Err(_) => panic!("Err"),
54 | };
55 | debug!("build_from_state:: {}",&str);
56 | serde_json::from_str(str).unwrap()
57 | }
58 |
59 | fn form_key(k: &String) -> String {
60 | format!("AssetPrivate#{}",k)
61 | }
62 | }
63 |
64 | impl WireBufferFromReturnType for WireBuffer {
65 | fn from_rt(self: &mut Self, s: AssetPrivate) {
66 | // we've got a wire buffer object and we need to set the bytes here from the string
67 | let json = serde_json::to_string(&s).unwrap();
68 | debug!("wire buffer returning the value {}",json.as_str());
69 | let buffer = json.into_bytes();
70 | self.buffer = Some(buffer);
71 | }
72 | }
73 |
74 | impl From<&WireBuffer> for AssetPrivate {
75 | fn from(wb: &WireBuffer) -> Self {
76 | match &wb.buffer {
77 | Some(buffer) => {
78 | match std::str::from_utf8(&buffer) {
79 | Ok(a) => serde_json::from_str(a).unwrap(),
80 | _ => unreachable!(),
81 | }
82 | }
83 | None => panic!(),
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/asset_transfer_secure_private_rs/src/types/transfer_receipt.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | use fabric_contract::contract::*;
5 | use fabric_contract::{blockchain::TransactionContext, data::*};
6 | use serde::{Deserialize, Serialize};
7 | use std::str::from_utf8;
8 |
9 | // Use the log crate to support logging
10 | use log::debug;
11 |
12 | #[derive(Serialize, Deserialize, Debug, Default)]
13 | pub struct TransferReceipt {
14 | id: String,
15 | txid: String,
16 | timestamp: String,
17 | }
18 |
19 | impl TransferReceipt {
20 | pub fn new(id: String) -> Self {
21 | let tx = TransactionContext::current_transaction();
22 | TransferReceipt {
23 | id,
24 | txid: tx.get_id(),
25 | timestamp: tx.get_timestamp(),
26 | }
27 | }
28 | }
29 |
30 | /// Very important to implement the DataType Trait for the Asset
31 | ///
32 | /// This provides the ability to store the data in the ledger
33 | impl DataType for TransferReceipt {
34 | fn to_state(&self) -> State {
35 | let json = serde_json::to_string(self).unwrap();
36 | debug!("ToState::{}", &json.as_str());
37 | let buffer = json.into_bytes();
38 | State::from((self.id.clone(), buffer))
39 | }
40 |
41 | fn get_key(&self) -> String {
42 | let k = format!("{}:{}",self.id,self.txid);
43 | TransferReceipt::form_key(&k)
44 | }
45 |
46 | fn build_from_state(state: State) -> Self {
47 | let b = state.value();
48 |
49 | let str = match from_utf8(&b) {
50 | Ok(a) => a,
51 | Err(_) => panic!("Err"),
52 | };
53 | debug!("build_from_state:: {}", &str);
54 | serde_json::from_str(str).unwrap()
55 | }
56 |
57 | fn form_key(k: &String) -> String {
58 | format!("TransferReceipt::{}",k)
59 | }
60 | }
61 |
62 | impl WireBufferFromReturnType for WireBuffer {
63 | fn from_rt(self: &mut Self, s: TransferReceipt) {
64 | // we've got a wire buffer object and we need to set the bytes here from the string
65 | let json = serde_json::to_string(&s).unwrap();
66 | debug!("wire buffer returning the value {}", json.as_str());
67 | let buffer = json.into_bytes();
68 | self.buffer = Some(buffer);
69 | }
70 | }
71 |
72 | impl From<&WireBuffer> for TransferReceipt {
73 | fn from(wb: &WireBuffer) -> Self {
74 | match &wb.buffer {
75 | Some(buffer) => match std::str::from_utf8(&buffer) {
76 | Ok(a) => serde_json::from_str(a).unwrap(),
77 | _ => unreachable!(),
78 | },
79 | None => panic!(),
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/docs/apidoc/src/asset_transfer_rs/types.rs.html:
--------------------------------------------------------------------------------
1 | types.rs.html -- source
1
2 | 2
3 |
4 | modasset;
5 | pubuseasset::AssetasAsset;
6 |
--------------------------------------------------------------------------------
/fabric_contract/src/ledgerapi/ledger.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | use crate::ledgerapi::collection::*;
5 |
6 | ///
7 | /// Ledger representing high level concept of the Fabric Blockchain network
8 | ///
9 | /// Provides the access points for
10 | /// - getting access to data in both world state and peer's private collections
11 | /// - invoking chaincode on this and other networks
12 | ///
13 | /// When a transaction is invoked, it takes place under a 'transactional context'
14 | /// This context can be queried to provide the current transaction id, and information
15 | /// about the identity requesting the transaction.
16 | ///
17 | /// All operations need to be done under this transactional context, therefore
18 | /// the context needs to be passed to obtain the Ledger instance
19 | ///
20 | /// # Example
21 | ///
22 | /// ```ignore
23 | /// use fabric_contract::contract::*;
24 | ///
25 | ///
26 | /// pub fn asset_exists(my_assset_id: String) -> Result {
27 | /// let ledger = Ledger::access_ledger();
28 | ///
29 | /// let world = ledger.get_collection(CollectionName::World);
30 | ///
31 | /// Ok(world.state_exists(&my_assset_id))
32 | ///
33 | /// }
34 | /// ```
35 | pub struct Ledger {}
36 |
37 | impl Ledger {
38 |
39 | /// Get the Ledger based on the current transactional context
40 | ///
41 | /// The Tranasctional Context is available via the [Transaction API](../../transaction/struct.Transaction.html)
42 | ///
43 | pub fn access_ledger() -> Ledger {
44 | Ledger::new()
45 | }
46 |
47 | // Private new function
48 | fn new() -> Ledger {
49 | Ledger {}
50 | }
51 |
52 | /// Return the collection based on the name
53 | ///
54 | /// The collection provides access to the put & get Fabric
55 | /// semantics of the underlying world state, or private data
56 | /// that is specified by the Collection name.
57 | ///
58 | /// # Example
59 | /// ```ignore
60 | /// use fabric_contract::contract::*;
61 | /// let ledger = Ledger::access_ledger();
62 | ///
63 | /// // get the collectin that is backed by the World State
64 | /// let world = ledger.get_collection(CollectionName::World);
65 | ///
66 | /// // get the collection that is backed by the Organization's Implicity Private Data Collection
67 | /// let orgs_collection = ledger.get_collection(CollectionName::Organization(String::from("org1")));
68 | ///
69 | /// // get the collection that is backed by the named Private Data Collection
70 | /// let private_collection = ledger.get_collection(CollectionName::Private(String::from("my_private_details")));
71 | /// ```
72 | pub fn get_collection(&self, name: CollectionName) -> Collection {
73 | Collection::new(name)
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/docs/apidoc/contract_macros/all.html:
--------------------------------------------------------------------------------
1 | List of all items in this crate
--------------------------------------------------------------------------------
/docs/apidoc/basic_contract_rs/all.html:
--------------------------------------------------------------------------------
1 | List of all items in this crate
--------------------------------------------------------------------------------
/docs/apidoc/fabric_contract_macros/all.html:
--------------------------------------------------------------------------------
1 | List of all items in this crate
15 |
--------------------------------------------------------------------------------
/docs/apidoc/asset_transfer_rs/all.html:
--------------------------------------------------------------------------------
1 | List of all items in this crate
14 |
--------------------------------------------------------------------------------
/docs/apidoc/asset_transfer_private_rs/all.html:
--------------------------------------------------------------------------------
1 | List of all items in this crate