比較智能合約中的數字時出錯(大數字)
我無法理解我們什麼時候需要將數字轉換為 bigNumbers 才能斷言相等。在某些情況下,我錯誤地錯過了將整數變數轉換為 bigNumber 並且它們沒有錯誤地工作。有人可以對同一件事提出更多的看法嗎?
Javascript 沒有 256 位數字類型。BN 庫以自己的內部格式將它們表示為對象。你從許多乙太坊函式中得到一個 256 位的數字,這些數字總是以 BN 形式返回。
一旦你習慣了它,它就沒有什麼奇怪的了。只需將所有內容都轉換為 BN,使用 BN 進行數學運算,並在需要可讀結果時使用字元串。請記住,JS 並不是唯一不能處理這些高精度數字的系統,例如數據庫可能是個問題。
2 ^ 256 = 10 ^ 77
這有效:
let value = "1234567890123456789012345678901234567890 ..." // good
…但這不是,因為 2 ^ 64 是 10 ^ 20,所以它太大了。這就是國陣可以提供的幫助。
let value = 1234567890123456789012345678901234567890 ... // fail
BN 具有用於
.add
、.sub
、.mul
等的方法(很多!),因為 JS 無法處理這些大數字,所以將所有內容轉換為 BN 並使用 BN 方法執行您的算術運算。他們希望所有論點都是 BN。它們是無損的並且始終有效。如果您的測試使用低精度數字,您可能會得到誤導性的結果和似乎有效的東西,但您會在生產中遇到問題。這是混亂的根源,所以我建議不要這樣做。JS 可能會非常努力,只是截斷低位來給出答案,但不一定是答案。啊。不要依賴 JS 類型和正常表達式來處理進出乙太坊的數據。考慮一個命名約定,如
myValueBN
.let xBN = web3.utils.toBN("1234567890123456789012345678901234567890"); let yBN = web3.utils.toBN("1"); let nextBN = xBN.add(yBN); // show me a base-10 interpretation of "next" console.log(nextBN.toString(10)); // "1234567890123456789012345678901234567891"
當然,在實踐中你會從一個函式中得到你的數字,比如說……
let resultBN = await myContract.getSomething(); // is BN if value is a uint256
然後你可以去:
let twoBN = web3.utils.toBN("2"); let halfBN = resultBN.div(twoBN); // this is nearly lossless even if there are many digits console.log(halfBN.toString(10));
作為對遇到此問題的其他人的警告。我說“幾乎”無損,因為除法是一種特殊情況。我們正在處理整數,因此舍入/截斷是不可避免的。BN 有一個
.mod
函式,因此您可以計算餘數併計算餘數。希望能幫助到你。