// File: openzeppelin-solidity/contracts/utils/Address.solpragmasolidity ^0.5.0;/**
* @dev Collection of functions related to the address type,
*/libraryAddress{
/**
* @dev Returns true if `account` is a contract.
*
* This test is non-exhaustive, and there may be false-negatives: during the
* execution of a contract's constructor, its address will be reported as
* not containing a contract.
*
* > It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*/functionisContract(address account) internalviewreturns (bool) {
// This method relies in extcodesize, which returns 0 for contracts in// construction, since the code is only stored at the end of the// constructor execution.uint256 size;
// solhint-disable-next-line no-inline-assemblyassembly {
size :=extcodesize(account)
}
return size >0;
}
}
Contract Source Code
File 2 of 13: Counters.sol
// File: openzeppelin-solidity/contracts/drafts/Counters.solpragmasolidity ^0.5.0;import"./SafeMath.sol";
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
* Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath
* overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
* directly accessed.
*/libraryCounters{
usingSafeMathforuint256;
structCounter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add// this feature: see https://github.com/ethereum/solidity/issues/4637uint256 _value; // default: 0
}
functioncurrent(Counter storage counter) internalviewreturns (uint256) {
return counter._value;
}
functionincrement(Counter storage counter) internal{
counter._value +=1;
}
functiondecrement(Counter storage counter) internal{
counter._value = counter._value.sub(1);
}
}
Contract Source Code
File 3 of 13: CustomERC721Metadata.sol
// File: contracts/CustomERC721Metadata.solpragmasolidity ^0.5.0;import"./ERC165.sol";
import"./ERC721.sol";
import"./ERC721Enumerable.sol";
/**
* ERC721 base contract without the concept of tokenUri as this is managed by the parent
*/contractCustomERC721MetadataisERC165, ERC721, ERC721Enumerable{
// Token namestringprivate _name;
// Token symbolstringprivate _symbol;
bytes4privateconstant _INTERFACE_ID_ERC721_METADATA =0x5b5e139f;
/**
* @dev Constructor function
*/constructor(stringmemory name, stringmemory symbol) public{
_name = name;
_symbol = symbol;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721_METADATA);
}
/**
* @dev Gets the token name
* @return string representing the token name
*/functionname() externalviewreturns (stringmemory) {
return _name;
}
/**
* @dev Gets the token symbol
* @return string representing the token symbol
*/functionsymbol() externalviewreturns (stringmemory) {
return _symbol;
}
}
Contract Source Code
File 4 of 13: ERC165.sol
// File: openzeppelin-solidity/contracts/introspection/ERC165.solpragmasolidity ^0.5.0;import"./IERC165.sol";
/**
* @dev Implementation of the `IERC165` interface.
*
* Contracts may inherit from this and call `_registerInterface` to declare
* their support of an interface.
*/contractERC165isIERC165{
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/bytes4privateconstant _INTERFACE_ID_ERC165 =0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/mapping(bytes4=>bool) private _supportedInterfaces;
constructor() internal{
// Derived contracts need only register support for their own interfaces,// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See `IERC165.supportsInterface`.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/functionsupportsInterface(bytes4 interfaceId)
externalviewreturns (bool)
{
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See `IERC165.supportsInterface`.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/function_registerInterface(bytes4 interfaceId) internal{
require(interfaceId !=0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] =true;
}
}
Contract Source Code
File 5 of 13: ERC721.sol
// File: openzeppelin-solidity/contracts/token/ERC721/ERC721.solpragmasolidity ^0.5.0;import"./ERC165.sol";
import"./IERC721.sol";
import"./SafeMath.sol";
import"./Address.sol";
import"./Counters.sol";
import"./IERC721Receiver.sol";
/**
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://eips.ethereum.org/EIPS/eip-721
*/contractERC721isERC165, IERC721{
usingSafeMathforuint256;
usingAddressforaddress;
usingCountersforCounters.Counter;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`// which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`bytes4privateconstant _ERC721_RECEIVED =0x150b7a02;
// Mapping from token ID to ownermapping(uint256=>address) private _tokenOwner;
// Mapping from token ID to approved addressmapping(uint256=>address) private _tokenApprovals;
// Mapping from owner to number of owned tokenmapping(address=> Counters.Counter) private _ownedTokensCount;
// Mapping from owner to operator approvalsmapping(address=>mapping(address=>bool)) private _operatorApprovals;
bytes4privateconstant _INTERFACE_ID_ERC721 =0x80ac58cd;
constructor() public{
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721);
}
functionbalanceOf(address owner) publicviewreturns (uint256) {
require(
owner !=address(0),
"ERC721: balance query for the zero address"
);
return _ownedTokensCount[owner].current();
}
functionownerOf(uint256 tokenId) publicviewreturns (address) {
address owner = _tokenOwner[tokenId];
require(
owner !=address(0),
"ERC721: owner query for nonexistent token"
);
return owner;
}
functionapprove(address to, uint256 tokenId) public{
address owner = ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
msg.sender== owner || isApprovedForAll(owner, msg.sender),
"ERC721: approve caller is not owner nor approved for all"
);
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
functiongetApproved(uint256 tokenId) publicviewreturns (address) {
require(
_exists(tokenId),
"ERC721: approved query for nonexistent token"
);
return _tokenApprovals[tokenId];
}
functionsetApprovalForAll(address to, bool approved) public{
require(to !=msg.sender, "ERC721: approve to caller");
_operatorApprovals[msg.sender][to] = approved;
emit ApprovalForAll(msg.sender, to, approved);
}
functionisApprovedForAll(address owner, address operator)
publicviewreturns (bool)
{
return _operatorApprovals[owner][operator];
}
functiontransferFrom(addressfrom,
address to,
uint256 tokenId
) public{
//solhint-disable-next-line max-line-lengthrequire(
_isApprovedOrOwner(msg.sender, tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_transferFrom(from, to, tokenId);
}
functionsafeTransferFrom(addressfrom,
address to,
uint256 tokenId
) public{
safeTransferFrom(from, to, tokenId, "");
}
functionsafeTransferFrom(addressfrom,
address to,
uint256 tokenId,
bytesmemory _data
) public{
transferFrom(from, to, tokenId);
require(
_checkOnERC721Received(from, to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
function_exists(uint256 tokenId) internalviewreturns (bool) {
address owner = _tokenOwner[tokenId];
return owner !=address(0);
}
function_isApprovedOrOwner(address spender, uint256 tokenId)
internalviewreturns (bool)
{
require(
_exists(tokenId),
"ERC721: operator query for nonexistent token"
);
address owner = ownerOf(tokenId);
return (spender == owner ||
getApproved(tokenId) == spender ||
isApprovedForAll(owner, spender));
}
function_mint(address to, uint256 tokenId) internal{
require(to !=address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_tokenOwner[tokenId] = to;
_ownedTokensCount[to].increment();
emit Transfer(address(0), to, tokenId);
}
function_burn(address owner, uint256 tokenId) internal{
require(
ownerOf(tokenId) == owner,
"ERC721: burn of token that is not own"
);
_clearApproval(tokenId);
_ownedTokensCount[owner].decrement();
_tokenOwner[tokenId] =address(0);
emit Transfer(owner, address(0), tokenId);
}
function_burn(uint256 tokenId) internal{
_burn(ownerOf(tokenId), tokenId);
}
function_transferFrom(addressfrom,
address to,
uint256 tokenId
) internal{
require(
ownerOf(tokenId) ==from,
"ERC721: transfer of token that is not own"
);
require(to !=address(0), "ERC721: transfer to the zero address");
_clearApproval(tokenId);
_ownedTokensCount[from].decrement();
_ownedTokensCount[to].increment();
_tokenOwner[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function_checkOnERC721Received(addressfrom,
address to,
uint256 tokenId,
bytesmemory _data
) internalreturns (bool) {
if (!to.isContract()) {
returntrue;
}
bytes4 retval = IERC721Receiver(to).onERC721Received(
msg.sender,
from,
tokenId,
_data
);
return (retval == _ERC721_RECEIVED);
}
function_clearApproval(uint256 tokenId) private{
if (_tokenApprovals[tokenId] !=address(0)) {
_tokenApprovals[tokenId] =address(0);
}
}
}
Contract Source Code
File 6 of 13: ERC721Enumerable.sol
// File: openzeppelin-solidity/contracts/token/ERC721/ERC721Enumerable.solpragmasolidity ^0.5.0;import"./ERC165.sol";
import"./ERC721.sol";
import"./IERC721Enumerable.sol";
/**
* @title ERC-721 Non-Fungible Token with optional enumeration extension logic
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/contractERC721EnumerableisERC165, ERC721, IERC721Enumerable{
// Mapping from owner to list of owned token IDsmapping(address=>uint256[]) private _ownedTokens;
// Mapping from token ID to index of the owner tokens listmapping(uint256=>uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumerationuint256[] private _allTokens;
// Mapping from token id to position in the allTokens arraymapping(uint256=>uint256) private _allTokensIndex;
/*
* bytes4(keccak256('totalSupply()')) == 0x18160ddd
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
* bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
*
* => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
*/bytes4privateconstant _INTERFACE_ID_ERC721_ENUMERABLE =0x780e9d63;
/**
* @dev Constructor function.
*/constructor() public{
// register the supported interface to conform to ERC721Enumerable via ERC165
_registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
}
/**
* @dev Gets the token ID at a given index of the tokens list of the requested owner.
* @param owner address owning the tokens list to be accessed
* @param index uint256 representing the index to be accessed of the requested tokens list
* @return uint256 token ID at the given index of the tokens list owned by the requested address
*/functiontokenOfOwnerByIndex(address owner, uint256 index)
publicviewreturns (uint256)
{
require(
index < balanceOf(owner),
"ERC721Enumerable: owner index out of bounds"
);
return _ownedTokens[owner][index];
}
/**
* @dev Gets the total amount of tokens stored by the contract.
* @return uint256 representing the total amount of tokens
*/functiontotalSupply() publicviewreturns (uint256) {
return _allTokens.length;
}
/**
* @dev Gets the token ID at a given index of all the tokens in this contract
* Reverts if the index is greater or equal to the total number of tokens.
* @param index uint256 representing the index to be accessed of the tokens list
* @return uint256 token ID at the given index of the tokens list
*/functiontokenByIndex(uint256 index) publicviewreturns (uint256) {
require(
index < totalSupply(),
"ERC721Enumerable: global index out of bounds"
);
return _allTokens[index];
}
/**
* @dev Internal function to transfer ownership of a given token ID to another address.
* As opposed to transferFrom, this imposes no restrictions on msg.sender.
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
*/function_transferFrom(addressfrom,
address to,
uint256 tokenId
) internal{
super._transferFrom(from, to, tokenId);
_removeTokenFromOwnerEnumeration(from, tokenId);
_addTokenToOwnerEnumeration(to, tokenId);
}
/**
* @dev Internal function to mint a new token.
* Reverts if the given token ID already exists.
* @param to address the beneficiary that will own the minted token
* @param tokenId uint256 ID of the token to be minted
*/function_mint(address to, uint256 tokenId) internal{
super._mint(to, tokenId);
_addTokenToOwnerEnumeration(to, tokenId);
_addTokenToAllTokensEnumeration(tokenId);
}
/**
* @dev Internal function to burn a specific token.
* Reverts if the token does not exist.
* Deprecated, use _burn(uint256) instead.
* @param owner owner of the token to burn
* @param tokenId uint256 ID of the token being burned
*/function_burn(address owner, uint256 tokenId) internal{
super._burn(owner, tokenId);
_removeTokenFromOwnerEnumeration(owner, tokenId);
// Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund
_ownedTokensIndex[tokenId] =0;
_removeTokenFromAllTokensEnumeration(tokenId);
}
/**
* @dev Gets the list of token IDs of the requested owner.
* @param owner address owning the tokens
* @return uint256[] List of token IDs owned by the requested address
*/function_tokensOfOwner(address owner)
internalviewreturns (uint256[] storage)
{
return _ownedTokens[owner];
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/function_addTokenToOwnerEnumeration(address to, uint256 tokenId) private{
_ownedTokensIndex[tokenId] = _ownedTokens[to].length;
_ownedTokens[to].push(tokenId);
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/function_addTokenToAllTokensEnumeration(uint256 tokenId) private{
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the _ownedTokensIndex mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/function_removeTokenFromOwnerEnumeration(addressfrom, uint256 tokenId)
private{
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and// then delete the last slot (swap and pop).uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessaryif (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
_ownedTokens[from].length--;
// Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by// lastTokenId, or just over the end of the array if the token was the last one).
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/function_removeTokenFromAllTokensEnumeration(uint256 tokenId) private{
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and// then delete the last slot (swap and pop).uint256 lastTokenIndex = _allTokens.length.sub(1);
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding// an 'if' statement (like in _removeTokenFromOwnerEnumeration)uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index// This also deletes the contents at the last position of the array
_allTokens.length--;
_allTokensIndex[tokenId] =0;
}
}
// File: openzeppelin-solidity/contracts/introspection/IERC165.solpragmasolidity ^0.5.0;/**
* @dev Interface of the ERC165 standard, as defined in the
* [EIP](https://eips.ethereum.org/EIPS/eip-165).
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others (`ERC165Checker`).
*
* For an implementation, see `ERC165`.
*/interfaceIERC165{
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/functionsupportsInterface(bytes4 interfaceId) externalviewreturns (bool);
}
Contract Source Code
File 9 of 13: IERC721.sol
// File: openzeppelin-solidity/contracts/token/ERC721/IERC721.solpragmasolidity ^0.5.0;import"./IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/contractIERC721isIERC165{
eventTransfer(addressindexedfrom,
addressindexed to,
uint256indexed tokenId
);
eventApproval(addressindexed owner,
addressindexed approved,
uint256indexed tokenId
);
eventApprovalForAll(addressindexed owner,
addressindexed operator,
bool approved
);
/**
* @dev Returns the number of NFTs in `owner`'s account.
*/functionbalanceOf(address owner) publicviewreturns (uint256 balance);
/**
* @dev Returns the owner of the NFT specified by `tokenId`.
*/functionownerOf(uint256 tokenId) publicviewreturns (address owner);
/**
* @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
* another (`to`).
*
*
*
* Requirements:
* - `from`, `to` cannot be zero.
* - `tokenId` must be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this
* NFT by either `approve` or `setApproveForAll`.
*/functionsafeTransferFrom(addressfrom,
address to,
uint256 tokenId
) public;
/**
* @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
* another (`to`).
*
* Requirements:
* - If the caller is not `from`, it must be approved to move this NFT by
* either `approve` or `setApproveForAll`.
*/functiontransferFrom(addressfrom,
address to,
uint256 tokenId
) public;
functionapprove(address to, uint256 tokenId) public;
functiongetApproved(uint256 tokenId)
publicviewreturns (address operator);
functionsetApprovalForAll(address operator, bool _approved) public;
functionisApprovedForAll(address owner, address operator)
publicviewreturns (bool);
functionsafeTransferFrom(addressfrom,
address to,
uint256 tokenId,
bytesmemory data
) public;
}
// File: openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.solpragmasolidity ^0.5.0;/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/contractIERC721Receiver{
functiononERC721Received(address operator,
addressfrom,
uint256 tokenId,
bytesmemory data
) publicreturns (bytes4);
}
Contract Source Code
File 12 of 13: SafeMath.sol
// File: openzeppelin-solidity/contracts/math/SafeMath.solpragmasolidity ^0.5.0;/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522if (a ==0) {
return0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
// Solidity only automatically asserts when dividing by 0require(b >0, "SafeMath: division by zero");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn c;
}
}
Contract Source Code
File 13 of 13: Strings.sol
// File: contracts/Strings.solpragmasolidity ^0.5.0;//https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sollibraryStrings{
functionstrConcat(stringmemory _a, stringmemory _b)
internalpurereturns (stringmemory _concatenatedString)
{
return strConcat(_a, _b, "", "", "");
}
functionstrConcat(stringmemory _a,
stringmemory _b,
stringmemory _c
) internalpurereturns (stringmemory _concatenatedString) {
return strConcat(_a, _b, _c, "", "");
}
functionstrConcat(stringmemory _a,
stringmemory _b,
stringmemory _c,
stringmemory _d
) internalpurereturns (stringmemory _concatenatedString) {
return strConcat(_a, _b, _c, _d, "");
}
functionstrConcat(stringmemory _a,
stringmemory _b,
stringmemory _c,
stringmemory _d,
stringmemory _e
) internalpurereturns (stringmemory _concatenatedString) {
bytesmemory _ba =bytes(_a);
bytesmemory _bb =bytes(_b);
bytesmemory _bc =bytes(_c);
bytesmemory _bd =bytes(_d);
bytesmemory _be =bytes(_e);
stringmemory abcde =newstring(
_ba.length+ _bb.length+ _bc.length+ _bd.length+ _be.length
);
bytesmemory babcde =bytes(abcde);
uint256 k =0;
uint256 i =0;
for (i =0; i < _ba.length; i++) {
babcde[k++] = _ba[i];
}
for (i =0; i < _bb.length; i++) {
babcde[k++] = _bb[i];
}
for (i =0; i < _bc.length; i++) {
babcde[k++] = _bc[i];
}
for (i =0; i < _bd.length; i++) {
babcde[k++] = _bd[i];
}
for (i =0; i < _be.length; i++) {
babcde[k++] = _be[i];
}
returnstring(babcde);
}
functionuint2str(uint256 _i)
internalpurereturns (stringmemory _uintAsString)
{
if (_i ==0) {
return"0";
}
uint256 j = _i;
uint256 len;
while (j !=0) {
len++;
j /=10;
}
bytesmemory bstr =newbytes(len);
uint256 k = len -1;
while (_i !=0) {
bstr[k--] =bytes1(uint8(48+ (_i %10)));
_i /=10;
}
returnstring(bstr);
}
}