Solidity
為什麼我的計算被破壞了?
我有一個持有代幣餘額的智能合約,我們稱之為
Token A
,使用者可以發送這個智能合約Token B
來接收Token A
,他們通過指定Token A
他們想要接收的數量來做到這一點,智能合約會自動計算Token B
他們將擁有的數量根據預定義的比率進行支出。問題是,在前端,我希望使用者能夠指定
Token B
他們想要花費的金額而不是Token A
他們想要收到的金額,所以我創建了一個函式來轉換使用者輸入的金額的Token B
toToken A
,它是這樣的:function convertBtoA(uint amountB) returns (uint) { return totalA.mul(amountB).div(totalB); }
使用者送出該函式的結果,然後智能合約將金額轉換回以
Token B
使用另一個函式確定支付:function convertAtoB(uint amountA) returns (uint) { return totalB.mul(amountA).div(totalA); }
但是,此函式的結果有時會與原始使用者輸入量略有不同,例如:
# given totalA == 195738239776775570; totalB == 59744193591648150 convertBtoA(50000000000000000) # output == 163813609331349736 convertAtoB(163813609331349736) # output == 49999999999999999
在上面的範例中,原始使用者輸入為
50000000000000000
,智能合約進行轉換的結果為49999999999999999
。我的問題是,有沒有辦法保證Token A
toToken B
和 back to的轉換Token A
導致每次都以相同的數字開始?注意:我不能
Token B
直接將使用者輸入的金額輸入到契約中而不轉換為,因為此契約有時用於通過收款Token A
支付,在這種情況下,我希望在 中指定使用者輸入。Token B``Token A``Token A
除非totalA等於totalB,否則並非所有情況都可行,在這種情況下,您將擁有amountB =amountA。
除法會截斷結果,丟棄小數位,在您的範例中,convertBtoA 的返回值應為 163813609331349736.27117520077928403。
對於大多數案例,可以接受小的捨入誤差,例如 ERC20 和 Ether 都有 18 位小數,因此 1/10^18 的誤差遠低於典型的交易費用。