From 9776282d181839fbb4b18f2cf218e316d6df871c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20S=C3=A1?= Date: Mon, 11 Feb 2019 20:00:07 +0000 Subject: [PATCH] v0.0.6 - Addition of several other typecast methods (#20) * Vanity updates * Add type cast method to `bytes32` * Update to the natSpec comment on top of both libraries :smile: Though I really like Nick Johnson's string library this has been built entirely by me (as opposed to what the NatSpec comment in the top said since the last commit :smile:) I just copied the comment layout on top of his library and forgot to change the author :joy: * Adding Solidity highlight to gitattribute :tada: :smile: * Update package versions & prepare for NPM publish * Create a NPM ignore file to keep `truffle.js` from being published * Syntax & pragmas updates for v0.5.0 * Update README to reflect NPM publish * Another README update * Support for typecasting into uint8, uint16, uint32 (#19) * Add uint8, uint16, uint32 * Unit test for uint8, uint16, uint32 * Removing Truffle as a dependency * Bump version to v0.0.6 --- README.md | 20 +++++++- contracts/BytesLib.sol | 33 ++++++++++++ ethpm.json | 2 +- package-lock.json | 111 ++--------------------------------------- package.json | 2 +- test/TestBytesLib2.sol | 86 ++++++++++++++++++++++++++++++- 6 files changed, 141 insertions(+), 113 deletions(-) diff --git a/README.md b/README.md index 9154987..816c9ca 100644 --- a/README.md +++ b/README.md @@ -31,12 +31,28 @@ and use the library `AssertBytes` much like they use `Assert` in Truffle's [exam ## EthPM -This library is published at EPM under the alias `bytes` +This library is published in EPM under the alias `bytes` **Installing it with Truffle** ``` -truffle install bytes +$ truffle install bytes +``` + +## NPM + +This library is published in NPM under the alias `solidity-bytes-utils` + +**Installing it with NPM** + +``` +$ npm install solidity-bytes-utils +``` + +**Importing it in your Solidity contract** + +``` +import "solidity-bytes-utils/BytesLib.sol"; ``` ## Contributing diff --git a/contracts/BytesLib.sol b/contracts/BytesLib.sol index e56daeb..d1120c2 100755 --- a/contracts/BytesLib.sol +++ b/contracts/BytesLib.sol @@ -286,6 +286,39 @@ library BytesLib { return tempAddress; } + function toUint8(bytes _bytes, uint _start) internal pure returns (uint8) { + require(_bytes.length >= (_start + 1)); + uint8 tempUint; + + assembly { + tempUint := mload(add(add(_bytes, 0x1), _start)) + } + + return tempUint; + } + + function toUint16(bytes _bytes, uint _start) internal pure returns (uint16) { + require(_bytes.length >= (_start + 2)); + uint16 tempUint; + + assembly { + tempUint := mload(add(add(_bytes, 0x2), _start)) + } + + return tempUint; + } + + function toUint32(bytes _bytes, uint _start) internal pure returns (uint32) { + require(_bytes.length >= (_start + 4)); + uint32 tempUint; + + assembly { + tempUint := mload(add(add(_bytes, 0x4), _start)) + } + + return tempUint; + } + function toUint(bytes _bytes, uint _start) internal pure returns (uint256) { require(_bytes.length >= (_start + 32)); uint256 tempUint; diff --git a/ethpm.json b/ethpm.json index 6333306..ee9712e 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "bytes", - "version": "0.0.5", + "version": "0.0.6", "description": "Solidity bytes tightly packed arrays utility library.", "authors": [ "Gonçalo Sá " diff --git a/package-lock.json b/package-lock.json index 9e55913..ddff890 100644 --- a/package-lock.json +++ b/package-lock.json @@ -657,12 +657,6 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, "browserify-aes": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", @@ -799,12 +793,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -940,12 +928,6 @@ "repeating": "^2.0.0" } }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, "dom-walk": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", @@ -1320,12 +1302,6 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -1356,12 +1332,6 @@ "ansi-regex": "^2.0.0" } }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, "hash-base": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", @@ -1399,12 +1369,6 @@ "secp256k1": "^3.0.1" } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -1926,44 +1890,6 @@ "minimist": "0.0.8" } }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2027,12 +1953,6 @@ "wrappy": "1" } }, - "original-require": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/original-require/-/original-require-1.0.1.tgz", - "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=", - "dev": true - }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -2624,32 +2544,6 @@ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, - "truffle": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/truffle/-/truffle-4.1.11.tgz", - "integrity": "sha512-VNhc6jexZeM92sNJJr4U8ln3uJ/mJEQO/0y9ZLYc4pccyIskPtl+3r4mzymgGM/Mq5v6MpoQVD6NZgHUVKX+Dw==", - "dev": true, - "requires": { - "mocha": "^4.1.0", - "original-require": "^1.0.1", - "solc": "0.4.24" - }, - "dependencies": { - "solc": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", - "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", - "dev": true, - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - } - } - } - }, "truffle-hdwallet-provider": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider/-/truffle-hdwallet-provider-0.0.3.tgz", @@ -2719,7 +2613,7 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", "integrity": "sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0=", "requires": { - "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "bignumber.js": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2": "*", @@ -2771,6 +2665,7 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.16.0.tgz", "integrity": "sha1-pFVBdc1GKUMDWx8dOUMvdBxrYBk=", "requires": { + "bignumber.js": "git+https://github.com/debris/bignumber.js.git#master", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xmlhttprequest": "*" @@ -2778,7 +2673,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "from": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9" + "from": "git+https://github.com/debris/bignumber.js.git#master" } } } diff --git a/package.json b/package.json index 6d7f3be..c8d320f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "solidity-bytes-utils", - "version": "0.0.5", + "version": "0.0.6", "description": "Solidity bytes tightly packed arrays utility library.", "main": "truffle.js", "repository": { diff --git a/test/TestBytesLib2.sol b/test/TestBytesLib2.sol index 761feca..61254c6 100755 --- a/test/TestBytesLib2.sol +++ b/test/TestBytesLib2.sol @@ -126,6 +126,90 @@ contract TestBytesLib2 { // This should throw; } + function testToUint8() public { + bytes memory memBytes = hex"f00d20feed"; + + uint8 testUint8 = 32; // 0x20 == 32 + uint8 resultUint8; + + resultUint8 = memBytes.toUint8(2); + Assert.equal(uint256(resultUint8), uint256(testUint8), "Typecast to 8-bit-wide unsigned integer failed."); + + // Now we're going to test for slicing actions that throw present in the functions below + // with a ThrowProxy contract + // v. http://truffleframework.com/tutorials/testing-for-throws-in-solidity-tests + ThrowProxy throwProxy = new ThrowProxy(address(this)); + + TestBytesLib2(address(throwProxy)).toUint8Throw(); + bool r = throwProxy.execute.gas(100000)(); + Assert.isFalse(r, "Typecasting with wrong index should throw"); + } + + function toUint8Throw() public pure { + bytes memory memBytes = hex"f00d42feed"; + + uint8 resultUint8; + + resultUint8 = memBytes.toUint8(35); + // This should throw; + } + + function testToUint16() public { + bytes memory memBytes = hex"f00d0020feed"; + + uint16 testUint16 = 32; // 0x20 == 32 + uint16 resultUint16; + + resultUint16 = memBytes.toUint16(2); + Assert.equal(uint256(resultUint16), uint256(testUint16), "Typecast to 16-bit-wide unsigned integer failed."); + + // Now we're going to test for slicing actions that throw present in the functions below + // with a ThrowProxy contract + // v. http://truffleframework.com/tutorials/testing-for-throws-in-solidity-tests + ThrowProxy throwProxy = new ThrowProxy(address(this)); + + TestBytesLib2(address(throwProxy)).toUint16Throw(); + bool r = throwProxy.execute.gas(100000)(); + Assert.isFalse(r, "Typecasting with wrong index should throw"); + } + + function toUint16Throw() public pure { + bytes memory memBytes = hex"f00d0042feed"; + + uint16 resultUint16; + + resultUint16 = memBytes.toUint16(35); + // This should throw; + } + + function testToUint32() public { + bytes memory memBytes = hex"f00d00000020feed"; + + uint32 testUint32 = 32; // 0x20 == 32 + uint32 resultUint32; + + resultUint32 = memBytes.toUint32(2); + Assert.equal(uint256(resultUint32), uint256(testUint32), "Typecast to 32-bit-wide unsigned integer failed."); + + // Now we're going to test for slicing actions that throw present in the functions below + // with a ThrowProxy contract + // v. http://truffleframework.com/tutorials/testing-for-throws-in-solidity-tests + ThrowProxy throwProxy = new ThrowProxy(address(this)); + + TestBytesLib2(address(throwProxy)).toUint32Throw(); + bool r = throwProxy.execute.gas(100000)(); + Assert.isFalse(r, "Typecasting with wrong index should throw"); + } + + function toUint32Throw() public pure { + bytes memory memBytes = hex"f00d00000042feed"; + + uint32 resultUint32; + + resultUint32 = memBytes.toUint32(35); + // This should throw; + } + function testToUint() public { bytes memory memBytes = hex"f00d0000000000000000000000000000000000000000000000000000000000000020feed"; @@ -133,7 +217,7 @@ contract TestBytesLib2 { uint256 resultUint; resultUint = memBytes.toUint(2); - Assert.equal(resultUint, testUint, "Typecast to unsigned integer failed."); + Assert.equal(resultUint, testUint, "Typecast to 256-bit-wide unsigned integer failed."); // Now we're going to test for slicing actions that throw present in the functions below // with a ThrowProxy contract