I would like to concatenate an Ethereum address to an uint in Solidity. How can I do that?
-
Define "concatenate" please.– goodvibrationNov 2, 2020 at 17:58
-
1"In formal language theory and computer programming, string concatenation is the operation of joining character strings end-to-end. For example, the concatenation of "snow" and "ball" is "snowball"."– Haya RaedNov 2, 2020 at 18:05
-
Neither one of these is a string though!– goodvibrationNov 2, 2020 at 18:07
-
you can concatenate anything. This is just an example. Concatenating 1 and happy gives 1happy– Haya RaedNov 2, 2020 at 18:08
-
So your challenge in not concatenating them, but converting each one of them to a string. Thus, your question is misleading, and assuming that you've conducted some preliminary research prior to posting it, there's a good chance that you've been searching for the wrong thing. On top of that, in contrast with your claims above, there is no formal (or even ad-hoc standard) definition for concatenation other than for between a pair of strings! Your example above includes the conversion of the first operand from an integer to a string!!!– goodvibrationNov 2, 2020 at 18:08
|
Show 2 more comments
1 Answer
You have not specified which base you want each operand represented by (for example, decimal base for the uint
operand and hexadecimal base for the address
operand), so here are the likely options:
pragma solidity 0.6.12;
contract MyContract {
function concatDecDec(uint256 x, address y) external pure returns (string memory) {
return string(abi.encodePacked(itod(x), itod(uint256(y))));
}
function concatDecHex(uint256 x, address y) external pure returns (string memory) {
return string(abi.encodePacked(itod(x), itoh(uint256(y))));
}
function concatHexDec(uint256 x, address y) external pure returns (string memory) {
return string(abi.encodePacked(itoh(x), itod(uint256(y))));
}
function concatHexHex(uint256 x, address y) external pure returns (string memory) {
return string(abi.encodePacked(itoh(x), itoh(uint256(y))));
}
function itod(uint256 x) private pure returns (string memory) {
if (x > 0) {
string memory str;
while (x > 0) {
str = string(abi.encodePacked(uint8(x % 10 + 48), str));
x /= 10;
}
return str;
}
return "0";
}
function itoh(uint256 x) private pure returns (string memory) {
if (x > 0) {
string memory str;
while (x > 0) {
str = string(abi.encodePacked(uint8(x % 16 + (x % 16 < 10 ? 48 : 87)), str));
x /= 16;
}
return str;
}
return "0";
}
}
Note that when executed in a transaction (i.e., from a non-constant contract function), each one of these functions may yield a relatively high gas-cost.
Here is a Truffle test of the contract above:
const MyContract = artifacts.require('MyContract');
const UINT256 = '99999999';
const ADDRESS = '0x1234567812345678123456781234567812345678';
contract('test', () => {
it('test', async () => {
const myContract = await MyContract.new();
const resultDecDec = await myContract.concatDecDec(UINT256, ADDRESS);
const resultDecHex = await myContract.concatDecHex(UINT256, ADDRESS);
const resultHexDec = await myContract.concatHexDec(UINT256, ADDRESS);
const resultHexHex = await myContract.concatHexHex(UINT256, ADDRESS);
assert.equal(resultDecDec, web3.utils.toBN(UINT256).toString(10) + web3.utils.toBN(ADDRESS).toString(10));
assert.equal(resultDecHex, web3.utils.toBN(UINT256).toString(10) + web3.utils.toBN(ADDRESS).toString(16));
assert.equal(resultHexDec, web3.utils.toBN(UINT256).toString(16) + web3.utils.toBN(ADDRESS).toString(10));
assert.equal(resultHexHex, web3.utils.toBN(UINT256).toString(16) + web3.utils.toBN(ADDRESS).toString(16));
});
});