91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用C#開發超級賬本Fabric

發布時間:2021-11-26 16:16:03 來源:億速云 閱讀:194 作者:iii 欄目:互聯網科技

本篇內容介紹了“怎么用C#開發超級賬本Fabric ”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1、Fabric鏈碼.NET Core開發包

首先創建一個.NET Core項目,在命令行執行如下命令添加對Fabric鏈碼.NET Core開發包的依賴:

dotnet add package Thinktecture.HyperledgerFabric.Chaincode \
  --version 1.0.0-prerelease.74

Thinktecture.HyperledgerFabric.Chaincode鏈碼開發包提供了兩種不同的方法來開發Hyperledger Fabric鏈碼。

  • 使用底層API:通過實現IChaincode接口來開發超級賬本Fabric鏈碼是一種比較底層的途徑, 好處是對鏈碼實現的掌控程度最大

  • 使用上層API:通過繼承ContractBase類來開發超級賬本Fabric鏈碼會更容易一些,但 代價就是喪失部分靈活性

在這個教程中,我們將通過IChaincode接口這一偏底層的途徑來實現Fabric鏈碼。如果你對ContractBase繼承實現更有興趣,請等待我們下一篇教程!

2、Hyperledger Fabric鏈碼開發

創建一個類AssetHolding來實現IChaincode接口:

public class AssetHolding : IChaincode
{
    public async Task<Response> Init(IChaincodeStub stub)
    {
        throw new NotImplementedException();
    }

    public Task<Response> Invoke(IChaincodeStub stub)
    {
        throw new NotImplementedException();
    }
}

Ichaincode接口的兩個方法Init和Invoke都需要實現。

Init()方法將在Fabric鏈碼初始化和升級時被調用,可以使用這個方法來初始化資產庫,例如, 設置一些默認值。

Invoke()方法將在Fabric鏈碼的整個生命周期中被Peer節點調用,可以使用這個方法來處理可能影響資產狀態的業務交易邏輯。

兩個方法都有一個類型為IChaincodeStub的參數,該接口封裝了Fabric鏈碼實現和Fabric對等節點之間的通信API。例如,使用這個接口可以對資產庫進行CRUD操作。

3、實現Hyperledger Fabric鏈碼的Init()方法

如前所述,我們的Fabric鏈碼需要初始化兩個賬戶名并設置賬戶初始余額。基本上應用在調用Fabric鏈碼時會傳遞一個數組參數給鏈碼,例如["accountA", "100", "accountB", "50"],為了在Fabric鏈碼初始化時得到這個參數,我們可以使用stub.GetFunctionAndParameters(),該方法的結果時一個List<String>類型的參數對象,其中包含了所有參數。

public async Task<Response> Init(IChaincodeStub stub)
{
    var functionAndParameters = stub.GetFunctionAndParameters();

    var args = functionAndParameters.Parameters;

    args.AssertCount(4);
}

我們使用Parameters.AssertCount(4)來快速檢查參數的數量是否符合要求,如果數量不是4就會拋出異常,從而終止鏈碼的執行。

下一步是將其中兩個參數轉換為整型。我們可以自己使用int.TryParse()來實現這一步,或者使用args.TryGet<int>()方法。現在我們來完善Init()的實現:

public async Task<Response> Init(IChaincodeStub stub)
{
    var functionAndParameters = stub.GetFunctionAndParameters();

    var args = functionAndParameters.Parameters;

    args.AssertCount(4);

    if (!args.TryGet<int>(1, out var aValue) ||
        !args.TryGet<int>(3, out var bValue))
    {
        return Shim.Error("Expecting integer value for asset holding");
    }
}

在上面的代碼中我們嘗試將第2個和第4個參數轉換為整數,如果某個轉換失敗,我們就返回Shim.Error()通知Fabric鏈碼的調用方初始化失敗。

如果轉換成功,我們就可以使用stub.PutState()將轉換結果存入鏈碼資產庫:

public async Task<Response> Init(IChaincodeStub stub)
{
    var functionAndParameters = stub.GetFunctionAndParameters();

    var args = functionAndParameters.Parameters;

    args.AssertCount(4);

    if (!args.TryGet<int>(1, out var aValue) ||
        !args.TryGet<int>(3, out var bValue))
    {
        return Shim.Error("Expecting integer value for asset holding");
    }

    if (await stub.PutState(args.Get<string>(0), aValue)
        && await stub.PutState(args.Get<string>(2), bValue))
    {
        return Shim.Success();
    }

    return Shim.Error("Error during Chaincode init!");
}

在上面的代碼中,我們使用PutState()來更新Faric鏈碼資產庫中賬戶的初始值。如果一切順利,我們就可以使用Shim.Success()向Fabric鏈碼調用者返回成功響應,否則返回一個錯誤。

4、實現Hyperledger Fabric鏈碼的Invoke()方法

現在我們進入Invoke方法的實現。Invoke()方法在鏈碼整個聲明周期中被Fabric的對等節點調用來處理業務邏輯,該方法的參數和Init()一樣,因此我們也需要使用該參數接口的GetFunctionAndParameters()方法來獲取Fabric鏈碼的調用參數。

public Task<Response> Invoke(IChaincodeStub stub)
{
    var functionAndParameters = stub.GetFunctionAndParamaters();

    if (functionAndParameters.Function == 'myfn1')
    {
      return MyFn1(stub, functionAndParameters.Parameters);
    }

    if (functionAndParameters.Function == 'myfn2')
    {
      return MyFn2(stub, functionAndParameters.Parameters);
    }

    // Rinse and repeat for every function
}

依賴于你的具體設計,在Invoke實現中可能需要很多if分支或switch分支,因此Faric鏈碼.NET開發包提供了一個輔助類ChaincodeInvocationMap來讓代碼更干凈:

private readonly ChaincodeInvocationMap _invocationMap;

public AssetHolding()
{
    _invocationMap = new ChaincodeInvocationMap
    {
        {"Transfer", InternalTransfer},
        {"Query", InternalQuery}
    };
}

public Task<Response> Invoke(IChaincodeStub stub)
{
    return _invocationMap.Invoke(stub);
}

需要指出的是,我們還沒有實現InternalTransfer()InternalQuery()方法。

下面實現InternalTransfer()方法:

private async Task<ByteString> InternalTransfer(IChaincodeStub stub, Parameters args)
{
    args.AssertCount(3);

    var accountA = args.Get<string>(0);
    var accountB = args.Get<string>(1);

    if (string.IsNullOrEmpty(accountA) || string.IsNullOrEmpty(accountB))
        throw new Exception("Asset holding must not be empty");

    var aValue = await stub.TryGetState<int>(accountA);
    if (!aValue.HasValue) throw new Exception("Failed to get state of asset holder A");

    var bValue = await stub.TryGetState<int>(accountB);
    if (!bValue.HasValue) throw new Exception("Failed to get state of asset holder B");

    if (!args.TryGet<int>(2, out var amount))
        throw new Exception("Expecting integer value for amount to be transferred");

    aValue -= amount;
    bValue += amount;

    await stub.PutState(accountA, aValue);
    await stub.PutState(accountB, bValue);

    return ByteString.Empty;
}

由于我們的Fabric鏈碼需要從一個賬戶向另一個賬戶轉錢,因此需要三個參數:

  • accountA:轉出賬戶

  • accountB:轉入賬戶

  • amount:轉賬金額

我們可以使用AssertCount(3)來確保得到3個參數,就像在Init()實現中的檢查一樣。然后,在我們轉賬之前,需要從Fabric鏈碼資產庫中讀取當前的賬戶狀態。為此,我們需要使用IChaincodeStub.GetState()方法或IChaincodeStub.TryGetState()方法,兩者的區別在于第二個方法不會拋出異常,僅僅在失敗時返回false。

從Fabric鏈碼資產庫中讀取了賬戶狀態后,我們可以從accountA中扣除轉賬金額,并向accountB加上這個金額。在這一步你可以根據自己的需要進行必要的檢查,例如轉賬金額不可以是負數。

在更新了兩個賬戶的狀態變量后,我們還需要將新的狀態使用stub.PutState()寫入資產庫。最后我們返回一個空的ByteString給Fabric鏈碼調用方表示沒有發生錯誤。

InternalQuery()方法用來查詢指定賬戶的余額,因此需要傳入一個參數表示要查詢的賬戶。

private async Task<ByteString> InternalQuery(IChaincodeStub stub, Parameters args)
{
    args.AssertCount(1);

    var a = args[0];

    var aValueBytes = await stub.GetState(a);

    if (aValueBytes == null) throw new Exception($"Failed to get state of asset holder {a}");

    return aValueBytes;
}

好了,現在我們完成了Fabric鏈碼的.NET/C#實現,不過別忘了實現作為.NET應用入口的Main()方法,我們需要在這里啟動鏈碼:

static async Task Main(string[] args)
{
    using (var provider = ChaincodeProviderConfiguration.Configure<AssetHolding>(args))
    {
        var shim = provider.GetRequiredService<Shim>();
        await shim.Start();
    }
}

“怎么用C#開發超級賬本Fabric ”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宜章县| 子洲县| 博客| 星座| 晋宁县| 北宁市| 洛扎县| 安徽省| 来宾市| 镇沅| 崇义县| 安多县| 湘潭市| 黄平县| 江华| 永康市| 苍南县| 电白县| 西峡县| 北海市| 沙坪坝区| 铁岭市| 肃宁县| 大港区| 白银市| 河西区| 乳源| 武宣县| 池州市| 缙云县| 康马县| 禹城市| 灵台县| 会同县| 区。| 莆田市| 丽水市| 永善县| 苏州市| 高陵县| 萝北县|