У меня есть приложение, которое принимает различные виды ввода через HTML-форму, но всегда в конечном итоге отправляет его в контракт как bytes32
. Ожидается, что другой контракт, который в конечном итоге потребляет данные, приведет их к ожидаемому типу, который может быть bytes32
, uint256
или int256
.
Для целых чисел без знака я беру BigNumber
объект, вызываю toString(16)
его, чтобы получить шестнадцатеричный код, затем дополняю его слева до 64 цифр и добавляю 0x
. Но для целых чисел со знаком, которые могут быть отрицательными, мне, по-видимому, нужно обрабатывать систему дополнения до двух; Каков правильный способ сделать это?
Использование BN.js, предложенное @Ismael:
function numStringToBytes32(num) {
var bn = new BN(num).toTwos(256);
return padToBytes32(bn.toString(16));
}
function bytes32ToNumString(bytes32str) {
bytes32str = bytes32str.replace(/^0x/, '');
var bn = new BN(bytes32str, 16).fromTwos(256);
return bn.toString();
}
function padToBytes32(n) {
while (n.length < 64) {
n = "0" + n;
}
return "0x" + n;
}
Этот код работает для меня:
var utf8 = require('utf8');
function padToBytes32(n) {
while (n.length < 64) {
n = n + "0";
}
return "0x" + n;
}
function fromUtf8(str) {
str = utf8.encode(str);
var hex = "";
for (var i = 0; i < str.length; i++) {
var code = str.charCodeAt(i);
if (code === 0) {
break;
}
var n = code.toString(16);
hex += n.length < 2 ? '0' + n : n;
}
return padToBytes32(hex);
};
// not tested yet...
function toUtf8(hex) {
// Find termination
var str = "";
var i = 0, l = hex.length;
if (hex.substring(0, 2) === '0x') {
i = 2;
}
for (; i < l; i += 2) {
var code = parseInt(hex.substr(i, 2), 16);
if (code === 0) {
break;
}
str += String.fromCharCode(code);
}
return utf8.decode(str);
};
module.exports = {
fromUtf8,
toUtf8
};
```
Использование только BN.js
let num = -1234;
let bytes32 = "0x"+(new BN(String(num))).toTwos(256).toString('hex',64);
Использование web3.js
let num = -1234;
let bytes32 = web3.eth.abi.encodeParameter('int256', String(num));
Это работает в смарт-контракте следующим образом:
pragma solidity ^0.5.0;
contract TestConversion {
int256 val;
function set(bytes32 _val) public {
val = int256(_val);
}
function get() public view returns(int256){
return val;
}
}
Исмаэль
toTwos
,fromTwos
которые можно использовать для получения дополнения до произвольной длины.