日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 物聯(lián)網(wǎng) > 區(qū)塊鏈
[導(dǎo)讀] 此博客文章的目標(biāo)受眾主要是熟悉區(qū)塊鏈和智能合約的開(kāi)發(fā)人員。并非所有開(kāi)發(fā)人員都具有豐富的經(jīng)濟(jì)和金融背景。因此,我們建議您閱讀關(guān)于這些金融方面的博文。 定義“智能發(fā)票” 我們的目標(biāo)是

此博客文章的目標(biāo)受眾主要是熟悉區(qū)塊鏈和智能合約的開(kāi)發(fā)人員。并非所有開(kāi)發(fā)人員都具有豐富的經(jīng)濟(jì)和金融背景。因此,我們建議您閱讀關(guān)于這些金融方面的博文。

定義“智能發(fā)票”

我們的目標(biāo)是展示我們?nèi)绾问褂弥悄芎霞s來(lái)指定和執(zhí)行現(xiàn)實(shí)世界發(fā)票的支付,從而將錢從買方轉(zhuǎn)移到賣方。更具體地說(shuō),我們希望實(shí)現(xiàn)一個(gè)功能,以確保一旦買方接受發(fā)票,他就承諾在到截止日期進(jìn)行付款。

創(chuàng)建以太坊智能合約時(shí)會(huì)存在某些限制,這些限制會(huì)影響如何構(gòu)建滿足這些目標(biāo)的解決方案。

在以太坊上,不可能執(zhí)行“觸發(fā)器”,“事件驅(qū)動(dòng)編程”,“觀察者模式”和類似的范例,在這些范例中,某些事情需要作為對(duì)其他事情的分離響應(yīng)發(fā)生。因此,我們無(wú)法實(shí)施在到期日自動(dòng)執(zhí)行付款轉(zhuǎn)帳的解決方案。相反,我們創(chuàng)建了一個(gè)流程,保證任何人都可以在達(dá)到截止日期后觸發(fā)付款執(zhí)行。

我們使用三個(gè)智能合約來(lái)結(jié)算真正的貿(mào)易發(fā)票,它們是:

智能發(fā)票

從設(shè)計(jì)的角度來(lái)看,智能發(fā)票合同需要盡可能簡(jiǎn)單。買方承諾支付,因此有必要審計(jì)和理解包括此類承諾在內(nèi)的所有可能后果。

智能發(fā)票包含付款金額、截止日期、付款方和付款受益人。受益人可以由當(dāng)前受益人更改。所有其他字段都是靜態(tài)的,這對(duì)于買方來(lái)說(shuō)非常重要,以便了解他所承諾的內(nèi)容。

智能發(fā)票代幣

我們還要將付款標(biāo)記化。我們通過(guò)為智能發(fā)票創(chuàng)建一個(gè)erc20令牌來(lái)實(shí)現(xiàn)這一點(diǎn)。這使持有人有權(quán)在基礎(chǔ)發(fā)票結(jié)算后獲得部分付款。我們這樣做是為了說(shuō)明智能發(fā)票的使用案例,例如在結(jié)算前出售您的發(fā)票代幣以獲得提前付款。

錢包

買方和賣方都創(chuàng)建并控制他們自己的智能合約錢包。這個(gè)錢包可以保持價(jià)值,在我們的案例中是DA并I與智能發(fā)票發(fā)生交互。買方可以承諾通過(guò)他的錢包支付給定的智能發(fā)票。承諾意味著任何人都可以強(qiáng)制買方錢包在到截止日期支付發(fā)票。

端到端測(cè)試觀察

使用以太坊的最大挑戰(zhàn)之一是獲得對(duì)解決方案的高度信任。對(duì)于需要通過(guò)實(shí)施的大量資金的企業(yè)部門尤其如此。

在這個(gè)項(xiàng)目中,我們關(guān)注的是圍繞單元測(cè)試的工具和開(kāi)發(fā)。在本節(jié)中,我們使用端到端測(cè)試來(lái)解釋創(chuàng)建、標(biāo)記化和執(zhí)行發(fā)票付款過(guò)程中涉及的所有步驟。

用于開(kāi)發(fā)的技術(shù)堆棧由:node.js、typescript、solidity和truffle框架組成。以下代碼段是端到端測(cè)試的一部分。我們還使用一個(gè)簡(jiǎn)單的cli在mainnet上執(zhí)行了一個(gè)引導(dǎo)。在此過(guò)程中我們結(jié)算了一張真實(shí)的發(fā)票,并在下面的步驟中為我們的polit添加了Etherscan鏈接。

1.買方和賣方應(yīng)各自擁有一個(gè)含有以太坊的帳戶。

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’),

),

);

第一步是檢查買方和賣方是否在其賬戶中都有以太幣。他們都必須支付在以太坊區(qū)塊鏈交易所含的gas費(fèi)用。

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標(biāo)準(zhǔn)的加密貨幣來(lái)完成這個(gè)項(xiàng)目,但我們選擇了DAI。首先,我們要求使用“穩(wěn)定幣”,因?yàn)槿魏纹髽I(yè)都不會(huì)接受加密貨幣匯率風(fēng)險(xiǎn)。其次,我們與Maker建立了合作伙伴關(guān)系。

在此步驟中,我們將DAI添加到買方的帳戶中。我們使用‘BigNumber’依賴關(guān)系來(lái)轉(zhuǎn)換所需格式的和(10到18倍1000的冪)。

3.買家創(chuàng)建錢包

assert.notExists(buyerWalleTInstance);

buyerWalletInstance = await SmartInvoiceWallet.new(

buyer,

mockDAITokenInstance.address,

{ from: buyer },

);

const buyerWalletAssetTokenAddress = await buyerWalletInstance.

assetToken();

assert.equal(buyerWalletAssetTokenAddress, mockDAITokenInstance.

address);

買方錢包可以持有DAI代幣并與智能發(fā)票進(jìn)行交互。

4.賣方創(chuàng)建錢包

assert.notExists(sellerWalletInstance);

sellerWalletInstance = await SmartInvoiceWallet.new(

seller,

mockDAITokenInstance.address,

{ from: seller },

);

const sellerWalletAssetTokenAddress = await sellerWalletInstance.

assetToken();

assert.equal(sellerWalletAssetTokenAddress, mockDAITokenInstance.

address);

5.賣方為買方創(chuàng)建一張貿(mào)易發(fā)票。

mockInvoice = {

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

amount: 70.5,

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

current time

};

assert.exists(mockInvoice);

通常貿(mào)易轉(zhuǎn)移平臺(tái)上會(huì)創(chuàng)建發(fā)票。發(fā)票ID將用作智能發(fā)票標(biāo)識(shí)符(以便買方知道應(yīng)向誰(shuí)付款)。為了我們的項(xiàng)目,我們創(chuàng)建了一個(gè)對(duì)象并添加了所需的屬性。

在試點(diǎn)中,我們使用了真正的貿(mào)易發(fā)票。

6.賣方為貿(mào)易轉(zhuǎn)移發(fā)票創(chuàng)建智能發(fā)票和代幣。

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);

這是賣方創(chuàng)建智能合同實(shí)例的步驟,該實(shí)例“wrap”有關(guān)自執(zhí)行發(fā)票的所有必要信息。

現(xiàn)在我們創(chuàng)建了一個(gè)智能發(fā)票。我們只需要買方承諾(在他核實(shí)了細(xì)節(jié)之后)。

7.買方承諾支付智能發(fā)票。

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,}

);

買方驗(yàn)證智能發(fā)票中的承諾金額是否與在貿(mào)易轉(zhuǎn)移平臺(tái)上創(chuàng)建的初始發(fā)票上確定的金額相同。之后,他承諾在執(zhí)行之日支付。

8.賣方擁有所有發(fā)票代幣并確認(rèn)買方已承諾支付。

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(),

);

現(xiàn)在是賣家的行動(dòng)時(shí)間。他首先檢查買方是否兌現(xiàn)承諾。至于我們現(xiàn)在關(guān)注的是,我們等到截止日期,然后賣方將觸發(fā)智能發(fā)票執(zhí)行。

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)

);

即使在整個(gè)這一步驟中沒(méi)有任何代理實(shí)際上采取任何行動(dòng),我們認(rèn)為如何測(cè)試時(shí)間是否實(shí)際按預(yù)期進(jìn)行測(cè)試將是非常有趣的。

10.買方將DAI轉(zhuǎn)移到自己的錢包中

const invoiceAmount = await smartInvoiceInstance.amount();

await mockDAITokenInstance.transfer(

buyerWalletInstance.address,

invoiceAmount,

{from: buyer,},

);

const buyerWalletBalance = await buyerWalletInstance.balance();

assert(

new BigNumber(buyerWalletBalance).isGreaterThanOrEqualTo

(invoiceAmount)

);

通常,在到截止日期期,買方應(yīng)該已經(jīng)將DAI轉(zhuǎn)移到自己的錢包中。以防買方?jīng)]有足夠的錢支付,在付款的時(shí)候,超出了這個(gè)項(xiàng)目資金的范圍。

11.賣方觸發(fā)支付智能發(fā)票

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),

);

是時(shí)候賣家結(jié)算智能發(fā)票了。 我們檢查智能發(fā)票狀態(tài)是否設(shè)置為“已提交”。這是真的,因?yàn)槲覀兛吹劫I方承諾在步驟7付款。此時(shí)賣方觸發(fā)智能發(fā)票。

由于每個(gè)代幣代表正好1 DAI,我們將令牌余額與發(fā)票金額進(jìn)行比較,以查看它們是否匹配。

12.賣方以交換DAI的方式兌換發(fā)票代幣

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)

);

現(xiàn)在賣方已經(jīng)結(jié)算了智能發(fā)票,他可以贖回買方欠他的DAI金額。

13.賣方將DAI從錢包轉(zhuǎn)移到自己的賬戶

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)

);

我們現(xiàn)在有了一個(gè)完整的流程,兩個(gè)代理在他們之間建立智能發(fā)票。如果供應(yīng)商希望從他的錢包中取出DAI,他可以這樣做。我們已經(jīng)包含了這個(gè)測(cè)試步驟,這樣我們就可以正確地從頭到尾地跟蹤資金。

最后的想法

這個(gè)試點(diǎn)是關(guān)于想象智能發(fā)票在以太坊世界中的運(yùn)作方式。 顯然,這個(gè)項(xiàng)目并不支持大量的發(fā)票發(fā)送,而是為了說(shuō)明智能合約和區(qū)塊鏈如何適應(yīng)B2B領(lǐng)域。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉