From fbbff535285fbff1a55a18af110b46eafb15f4bf Mon Sep 17 00:00:00 2001 From: Andrew B Coathup <28278242+abcoathup@users.noreply.github.com> Date: Tue, 28 May 2019 02:31:09 +1000 Subject: [PATCH] Strings library (#1746) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feature Issue #1745 * Feature Issue #1745 remove whitespace in contract * Feature Issue #1745 fix Solidity linter issues * Feature Issue #1745 fix JS lint issues * Update contracts/drafts/Strings.sol Co-Authored-By: Nicolás Venturo * Update contracts/drafts/Strings.sol Co-Authored-By: Nicolás Venturo * Update contracts/drafts/Strings.sol Co-Authored-By: Nicolás Venturo * Updates based on PR feedback * Remove trailing whitespace * Update tests based on @nventuro feedback * Removed return name * Rename length as suggested * Rename temp variables in uint256ToString * Renamed bytes variable to buffer * Change concatenate to use abi.encodePacked * Moved OraclizeAPI reference to unit256ToString * Add emoji concat test * Remove concatenate * Remove concatenate from StringsMock and test * Rename function to fromUint256 * Update StringsMock.sol --- contracts/drafts/Strings.sol | 38 +++++++++++++++++++++++++++++++++ contracts/mocks/StringsMock.sol | 9 ++++++++ test/drafts/Strings.test.js | 23 ++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 contracts/drafts/Strings.sol create mode 100644 contracts/mocks/StringsMock.sol create mode 100644 test/drafts/Strings.test.js diff --git a/contracts/drafts/Strings.sol b/contracts/drafts/Strings.sol new file mode 100644 index 000000000..04a122811 --- /dev/null +++ b/contracts/drafts/Strings.sol @@ -0,0 +1,38 @@ +pragma solidity ^0.5.0; + +/** + * @title Strings + * @dev String operations. + */ +library Strings { + /** + * Concatenates two strings. + * string(abi.encodePacked(a, b)) + * https://solidity.readthedocs.io/en/latest/types.html?highlight=concatenate + */ + + /** + * @dev Converts a uint256 to a string. + * via OraclizeAPI - MIT licence + * https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol + */ + function fromUint256(uint256 value) internal pure returns (string memory) { + if (value == 0) { + return "0"; + } + uint256 temp = value; + uint256 digits; + while (temp != 0) { + digits++; + temp /= 10; + } + bytes memory buffer = new bytes(digits); + uint256 index = digits - 1; + temp = value; + while (temp != 0) { + buffer[index--] = byte(uint8(48 + temp % 10)); + temp /= 10; + } + return string(buffer); + } +} diff --git a/contracts/mocks/StringsMock.sol b/contracts/mocks/StringsMock.sol new file mode 100644 index 000000000..3b28a70e8 --- /dev/null +++ b/contracts/mocks/StringsMock.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.5.0; + +import "../drafts/Strings.sol"; + +contract StringsMock { + function fromUint256(uint256 value) public pure returns (string memory) { + return Strings.fromUint256(value); + } +} diff --git a/test/drafts/Strings.test.js b/test/drafts/Strings.test.js new file mode 100644 index 000000000..a4bf1398f --- /dev/null +++ b/test/drafts/Strings.test.js @@ -0,0 +1,23 @@ +const { constants } = require('openzeppelin-test-helpers'); + +const StringsMock = artifacts.require('StringsMock'); + +contract('Strings', function () { + beforeEach(async function () { + this.strings = await StringsMock.new(); + }); + + describe('from uint256', function () { + it('converts 0', async function () { + (await this.strings.fromUint256(0)).should.equal('0'); + }); + + it('converts a positive number', async function () { + (await this.strings.fromUint256(4132)).should.equal('4132'); + }); + + it('converts MAX_UINT256', async function () { + (await this.strings.fromUint256(constants.MAX_UINT256)).should.equal(constants.MAX_UINT256.toString()); + }); + }); +});