怎么用C#开发超级账本Fabric

技术怎么用C#开发超级账本Fabric本篇内容介绍了“怎么用C#开发超级账本Fabric ”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读

本文介绍了“如何用C#开发超级账本Fabric”的相关知识。很多人在实际办案过程中都会遇到这样的困难。接下来,让边肖带领大家学习如何应对这些情况!希望大家认真阅读,学点东西!

00-1010首先,创建一个. NET Core项目,并在命令行上执行以下命令来添加对Fabric链代码的依赖。NET核心开发包:

dotnetaddpackageThinktecture。HyperledgerFabric.Chaincode\

-版本1 . 0 . 0-预发行版。74 thinktecture。Hyperledger结构链代码开发工具包提供了两种不同的方法来开发hyperledger结构链代码。

使用底层API:通过实现IChaincode接口开发超级账本Fabric链代码是一种相对低级的方式。优点是它对链代码实现有最大的控制权。

使用上层API:通过继承ContractBase类开发超级账本Fabric链代码更容易,但代价是失去了一些灵活性。

在本教程中,我们将通过IChaincode接口实现Fabric链代码。如果您对ContractBase继承的实现更感兴趣,请等待我们的下一个教程!

00-1010创建一个类资产列表来实现IChaincode接口:

public classassertholding : ichincode

{

publicatasynctasresponsenit(ichincodestubstub)

{

thrownewnotimplementdexception();

}

publicattasresponseinvoke(ichincodestubstub)

{

thrownewnotimplementdexception();

}

} Ichaincode接口的Init和Invoke两种方法都需要实现。

初始化和升级结构链代码时,将调用Init()方法。此方法可用于初始化资产库,例如,设置一些默认值。

在结构链代码的整个生命周期中,对等节点将调用Invoke()方法。这种方法可以用来处理可能影响资产状态的业务交易逻辑。

这两种方法都有一个类型为IChaincodeStub的参数,它封装了Fabric链代码的实现和Fabric的对等节点之间的通信API。例如,这个接口可以用来对资产库执行CRUD操作。

1、Fabric链码.NET Core开发包

如前所述,我们的Fabric链代码需要初始化两个帐户名并设置初始帐户余额。基本上,当调用Fabric链代码时,应用程序将向链代码传递一个数组参数,例如['Accounta ',' 100 ',' Accountb ',' 50']。为了在初始化Fabric链代码时获得这个参数,我们可以使用存根。GetFunctionAndParameters()。这个方法的结果是一个列表字符串类型的参数对象,它包含所有的参数。

publicatasynctasresponsenit(ichincodestubstub)

{

varfunctionAndParameters=存根。GetFunctionAndParameters();

varargs=functionAndParameters。参数;

啊。Asse

rtCount(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 ”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/118937.html

(0)

相关推荐

  • C#的二次开发及应用举例分析

    技术C#的二次开发及应用举例分析本篇内容主要讲解“C#的二次开发及应用举例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#的二次开发及应用举例分析”吧!二次开发及应用

    攻略 2021年11月26日
  • 心形线,如何用几何画板画出笛卡尔心形线

    技术心形线,如何用几何画板画出笛卡尔心形线1心形线、新建参数。右键绘图区空白处,“新建参数”,标签为a,数值为4,单位“无”。
    2、快捷键“Ctrl+G”,调出绘制新函数编辑器。点“方程”,选极坐标方程。在编辑

    生活 2021年10月30日
  • 什么是javascript超集

    技术什么是javascript超集本篇内容介绍了“什么是javascript超集”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有

    攻略 2021年10月25日
  • python字典一些常见的魔法方法以及遇到的面试题有哪些

    技术python字典一些常见的魔法方法以及遇到的面试题有哪些本篇文章给大家分享的是有关python字典一些常见的魔法方法以及遇到的面试题有哪些,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,

    攻略 2021年10月21日
  • Jmeter中使用循环如何保证数据不重复

    技术Jmeter中使用循环如何保证数据不重复本篇文章为大家展示了Jmeter中使用循环如何保证数据不重复,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。在Jmeter中设置并发为S

    攻略 2021年11月17日
  • 589. N 叉树的前序遍历

    技术589. N 叉树的前序遍历 589. N 叉树的前序遍历给定一个 N 叉树,返回其节点值的 前序遍历 。
    N 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)

    礼包 2021年12月20日