Ich habe eine App, die verschiedene Arten von Eingaben über ein HTML-Formular entgegennimmt, sie aber immer als bytes32
. Die Erwartung ist, dass ein anderer Vertrag, der die Daten letztendlich verbraucht, sie in den erwarteten Typ umwandelt, der bytes32
, uint256
oder sein kann int256
.
Für Ganzzahlen ohne Vorzeichen nehme ich ein BigNumber
Objekt, rufe toString(16)
es auf, um Hex zu erhalten, fülle es dann mit der linken Maustaste auf 64 Ziffern auf und hänge 0x
. Aber für ganze Zahlen mit Vorzeichen, die negativ sein können, muss ich vermutlich mit dem Zweierkomplementsystem umgehen; Was ist der geeignete Weg, dies zu tun?
Verwendung von BN.js wie von @Ismael vorgeschlagen:
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;
}
Dieser Code funktioniert bei mir:
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
};
```
Verwenden Sie nur BN.js
let num = -1234;
let bytes32 = "0x"+(new BN(String(num))).toTwos(256).toString('hex',64);
Verwenden von web3.js
let num = -1234;
let bytes32 = web3.eth.abi.encodeParameter('int256', String(num));
Dies funktioniert im Smart-Contract wie folgt:
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;
}
}
Ismael
toTwos
,fromTwos
mit denen das Zweierkomplement auf eine beliebige Länge gebracht werden kann.