当前位置:首页 > 物联网 > 区块链
[导读] 此博客文章的目标受众主要是熟悉区块链和智能合约的开发人员。并非所有开发人员都具有丰富的经济和金融背景。因此,我们建议您阅读关于这些金融方面的博文。 定义“智能发票” 我们的目标是

此博客文章的目标受众主要是熟悉区块链和智能合约的开发人员。并非所有开发人员都具有丰富的经济和金融背景。因此,我们建议您阅读关于这些金融方面的博文。

定义“智能发票”

我们的目标是展示我们如何使用智能合约来指定和执行现实世界发票的支付,从而将钱从买方转移到卖方。更具体地说,我们希望实现一个功能,以确保一旦买方接受发票,他就承诺在到截止日期进行付款。

创建以太坊智能合约时会存在某些限制,这些限制会影响如何构建满足这些目标的解决方案。

在以太坊上,不可能执行“触发器”,“事件驱动编程”,“观察者模式”和类似的范例,在这些范例中,某些事情需要作为对其他事情的分离响应发生。因此,我们无法实施在到期日自动执行付款转帐的解决方案。相反,我们创建了一个流程,保证任何人都可以在达到截止日期后触发付款执行。

我们使用三个智能合约来结算真正的贸易发票,它们是:

智能发票

从设计的角度来看,智能发票合同需要尽可能简单。买方承诺支付,因此有必要审计和理解包括此类承诺在内的所有可能后果。

智能发票包含付款金额、截止日期、付款方和付款受益人。受益人可以由当前受益人更改。所有其他字段都是静态的,这对于买方来说非常重要,以便了解他所承诺的内容。

智能发票代币

我们还要将付款标记化。我们通过为智能发票创建一个erc20令牌来实现这一点。这使持有人有权在基础发票结算后获得部分付款。我们这样做是为了说明智能发票的使用案例,例如在结算前出售您的发票代币以获得提前付款。

钱包

买方和卖方都创建并控制他们自己的智能合约钱包。这个钱包可以保持价值,在我们的案例中是DA并I与智能发票发生交互。买方可以承诺通过他的钱包支付给定的智能发票。承诺意味着任何人都可以强制买方钱包在到截止日期支付发票。

端到端测试观察

使用以太坊的最大挑战之一是获得对解决方案的高度信任。对于需要通过实施的大量资金的企业部门尤其如此。

在这个项目中,我们关注的是围绕单元测试的工具和开发。在本节中,我们使用端到端测试来解释创建、标记化和执行发票付款过程中涉及的所有步骤。

用于开发的技术堆栈由:node.js、typescript、solidity和truffle框架组成。以下代码段是端到端测试的一部分。我们还使用一个简单的cli在mainnet上执行了一个引导。在此过程中我们结算了一张真实的发票,并在下面的步骤中为我们的polit添加了Etherscan链接。

1.买方和卖方应各自拥有一个含有以太坊的帐户。

const buyerBalance = await web3.eth.getBalance(buyer);

assert(

new BigNumber(buyerBalance).isGreaterThanOrEqualTo(

web3.utils.toWei(‘10’, ‘ether’),

),

);

const sellerBalance = await web3.eth.getBalance(seller);

assert(

new BigNumber(sellerBalance).isGreaterThanOrEqualTo(

web3.uTIls.toWei(‘10’, ‘ether’),

),

);

第一步是检查买方和卖方是否在其账户中都有以太币。他们都必须支付在以太坊区块链交易所含的gas费用。

2.买方在其账户中存有DAI(而不是在钱包中)。

const daiDecimals = await mockDAITokenInstance.decimals();

// give buyer 1000 DAI

const daiAmount = new BigNumber(10).pow(daiDecimals).TImes(1000);

await mockDAITokenInstance.setBalance(buyer, daiAmount.toString(10));

const smartContractBalance = await mockDAITokenInstance.balanceOf

(buyer);

assert.equal(smartContractBalance.toString(10), daiAmount.toString(10));

assert.notExists(buyerWalleTInstance);

我们可以使用任何符合ERC20标准的加密货币来完成这个项目,但我们选择了DAI。首先,我们要求使用“稳定币”,因为任何企业都不会接受加密货币汇率风险。其次,我们与Maker建立了合作伙伴关系。

在此步骤中,我们将DAI添加到买方的帐户中。我们使用‘BigNumber’依赖关系来转换所需格式的和(10到18倍1000的幂)。

3.买家创建钱包

assert.notExists(buyerWalleTInstance);

buyerWalletInstance = await SmartInvoiceWallet.new(

buyer,

mockDAITokenInstance.address,

{ from: buyer },

);

const buyerWalletAssetTokenAddress = await buyerWalletInstance.

assetToken();

assert.equal(buyerWalletAssetTokenAddress, mockDAITokenInstance.

address);

买方钱包可以持有DAI代币并与智能发票进行交互。

4.卖方创建钱包

assert.notExists(sellerWalletInstance);

sellerWalletInstance = await SmartInvoiceWallet.new(

seller,

mockDAITokenInstance.address,

{ from: seller },

);

const sellerWalletAssetTokenAddress = await sellerWalletInstance.

assetToken();

assert.equal(sellerWalletAssetTokenAddress, mockDAITokenInstance.

address);

5.卖方为买方创建一张贸易发票。

mockInvoice = {

id: ‘xxx-xx–xxxx-xxxx–xxxxxxxx’, // “random” uuid

amount: 70.5,

dueDate: currentTimeStamp() + 60 * 60, // 1h starting from

current time

};

assert.exists(mockInvoice);

通常贸易转移平台上会创建发票。发票ID将用作智能发票标识符(以便买方知道应向谁付款)。为了我们的项目,我们创建了一个对象并添加了所需的属性。

在试点中,我们使用了真正的贸易发票。

6.卖方为贸易转移发票创建智能发票和代币。

assert.exists(sellerWalletInstance);

assert.exists(mockInvoice);

assert.notExists(smartInvoiceTokenInstance);

assert.notExists(smartInvoiceInstance);

const daiDecimals = await mockDAITokenInstance.decimals();

const amount = new BigNumber(10)

.pow(daiDecimals)

.times(mockInvoice.amount);

smartInvoiceTokenInstance = await SmartInvoiceToken.new(

amount,

mockInvoice.dueDate,

mockDAITokenInstance.address,

sellerWalletInstance.address,

buyerWalletInstance.address,

mockInvoice.id,

{ from: seller },

);

const smartInvoiceAddress = await smartInvoiceTokenInstance.

smartInvoice();

// at is mistyped, and does returns a promise

smartInvoiceInstance = await SmartInvoice.at(smartInvoiceAddress);

assert.exists(smartInvoiceInstance);

assert.exists(smartInvoiceAddress);

这是卖方创建智能合同实例的步骤,该实例“wrap”有关自执行发票的所有必要信息。

现在我们创建了一个智能发票。我们只需要买方承诺(在他核实了细节之后)。

7.买方承诺支付智能发票。

const amountToCommit = await smartInvoiceInstance.amount();

const dueDateToCommit = await smartInvoiceInstance.dueDate();

const invoiceIdToCommit = await smartInvoiceInstance.referenceHash();

const daiDecimals = await mockDAITokenInstance.decimals();

const mockInvoiceAmount = new BigNumber(10)

.pow(daiDecimals)

.times(mockInvoice.amount);

// check if commitment value is correct

assert.equal(

amountToCommit.valueOf(),mockInvoiceAmount.valueOf(),

);

assert.equal(dueDateToCommit.toNumber(), mockInvoice.dueDate);

assert.equal(invoiceIdToCommit, mockInvoice.id);

await buyerWalletInstance.commit(

smartInvoiceInstance.address, {from: buyer,}

);

买方验证智能发票中的承诺金额是否与在贸易转移平台上创建的初始发票上确定的金额相同。之后,他承诺在执行之日支付。

8.卖方拥有所有发票代币并确认买方已承诺支付。

const validCommit = await buyerWalletInstance.hasValidCommit(

smartInvoiceInstance.address,{ from: seller },

);

assert.equal(validCommit, true);

const daiDecimals = await mockDAITokenInstance.decimals();

const mockInvoiceAmount = new BigNumber(10)

.pow(daiDecimals)

.times(mockInvoice.amount);

const sellerTokenBalance = await sellerWalletInstance.

invoiceTokenBalance(

smartInvoiceTokenInstance.address, {from: seller}

);

assert.equal(

sellerTokenBalance.valueOf(),mockInvoiceAmount.valueOf(),

);

现在是卖家的行动时间。他首先检查买方是否兑现承诺。至于我们现在关注的是,我们等到截止日期,然后卖方将触发智能发票执行。

9.截止日期到期

const initialBlock = await web3.eth.getBlock(‘latest’);

const timeToAdvance = 60 * 60;

const latestBlock: Block = await advanceTimeAndBlock(timeToAdvance);

assert.notEqual(initialBlock.hash, latestBlock.hash);

// assert if block time increased as expected

assert(

new BigNumber(initialBlock.timestamp)

.plus(timeToAdvance)

.isLessThanOrEqualTo(latestBlock.timestamp)

);

即使在整个这一步骤中没有任何代理实际上采取任何行动,我们认为如何测试时间是否实际按预期进行测试将是非常有趣的。

10.买方将DAI转移到自己的钱包中

const invoiceAmount = await smartInvoiceInstance.amount();

await mockDAITokenInstance.transfer(

buyerWalletInstance.address,

invoiceAmount,

{from: buyer,},

);

const buyerWalletBalance = await buyerWalletInstance.balance();

assert(

new BigNumber(buyerWalletBalance).isGreaterThanOrEqualTo

(invoiceAmount)

);

通常,在到截止日期期,买方应该已经将DAI转移到自己的钱包中。以防买方没有足够的钱支付,在付款的时候,超出了这个项目资金的范围。

11.卖方触发支付智能发票

const canSettle = await buyerWalletInstance

.canSettleSmartInvoice(smartInvoiceInstance.address);

assert.equal(true, canSettle);

// smart invoice is triggered by seller

await buyerWalletInstance.settle(

smartInvoiceInstance.address, {from: seller,}

);

const smartInvoiceTokenInstanceBalance = await mockDAITokenInstance

.balanceOf(smartInvoiceTokenInstance.address,);

const smartInvoiceAmount = await smartInvoiceInstance.amount();

assert.equal(

smartInvoiceTokenInstanceBalance.toString(10),

smartInvoiceAmount.toString(10),

);

是时候卖家结算智能发票了。 我们检查智能发票状态是否设置为“已提交”。这是真的,因为我们看到买方承诺在步骤7付款。此时卖方触发智能发票。

由于每个代币代表正好1 DAI,我们将令牌余额与发票金额进行比较,以查看它们是否匹配。

12.卖方以交换DAI的方式兑换发票代币

const canRedeem = await smartInvoiceTokenInstance.canRedeem();

assert.equal(true, canRedeem);

const sellerWalletBalanceBefore = await sellerWalletInstance.balance

({from: seller});

await sellerWalletInstance

.redeem(smartInvoiceTokenInstance.address, {from: seller,});

const sellerWalletBalanceAfter = await sellerWalletInstance

.balance({ from: seller });

const daiDecimals = await mockDAITokenInstance.decimals();

const daiInvoiceAmount = new BigNumber(10)

.pow(daiDecimals)

.times(mockInvoice.amount);

assert.equal(

daiInvoiceAmount.toString(10),

new BigNumber(sellerWalletBalanceAfter).minus(

sellerWalletBalanceBefore).toString(10)

);

现在卖方已经结算了智能发票,他可以赎回买方欠他的DAI金额。

13.卖方将DAI从钱包转移到自己的账户

const sellerBalanceBefore = await mockDAITokenInstance

.balanceOf(seller, { from: seller });

const daiDecimals = await mockDAITokenInstance.decimals();

const daiInvoiceAmount = new BigNumber(10)

.pow(daiDecimals)

.times(mockInvoice.amount);

await sellerWalletInstance

.transfer(seller, daiInvoiceAmount, {from: seller});

const sellerBalanceAfter = await mockDAITokenInstance

.balanceOf(seller, { from: seller });

assert.equal(

daiInvoiceAmount.toString(10),

new BigNumber(sellerBalanceAfter).minus(sellerBalanceBefore)。

toString(10)

);

我们现在有了一个完整的流程,两个代理在他们之间建立智能发票。如果供应商希望从他的钱包中取出DAI,他可以这样做。我们已经包含了这个测试步骤,这样我们就可以正确地从头到尾地跟踪资金。

最后的想法

这个试点是关于想象智能发票在以太坊世界中的运作方式。 显然,这个项目并不支持大量的发票发送,而是为了说明智能合约和区块链如何适应B2B领域。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭