From f38a863c2dcc05d349a16f7747f5013752be8395 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Thu, 28 Mar 2019 20:12:26 +0100 Subject: [PATCH 1/3] registry-generator : Fixes for Solidity 0.5.2 --- .../PatternCodeGen/CodeGen/CodeGen.cs | 2 - .../CodeGen/Registry/JSONGen.cs | 1 - .../CodeGen/Registry/RegistryContractGen.cs | 9 +- .../PatternCodeGen/CodeGen/Registry/SolGen.cs | 143 ++++++++++++------ .../CodeGen/Registry/UtilsGen.cs | 49 +++--- .../PatternCodeGen/PatternCodeGen.csproj | 7 - .../PatternCodeGen/Views/Home/Index.cshtml | 16 +- 7 files changed, 133 insertions(+), 94 deletions(-) diff --git a/accelerators/registry-generator/PatternCodeGen/CodeGen/CodeGen.cs b/accelerators/registry-generator/PatternCodeGen/CodeGen/CodeGen.cs index 4325b834..85eaef69 100644 --- a/accelerators/registry-generator/PatternCodeGen/CodeGen/CodeGen.cs +++ b/accelerators/registry-generator/PatternCodeGen/CodeGen/CodeGen.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Schema; using System.ComponentModel.DataAnnotations; diff --git a/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/JSONGen.cs b/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/JSONGen.cs index 9d90cca3..11faad16 100644 --- a/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/JSONGen.cs +++ b/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/JSONGen.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Web; namespace PatternCodeGen.CodeGen { diff --git a/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/RegistryContractGen.cs b/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/RegistryContractGen.cs index bb5dd393..d8fb95e6 100644 --- a/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/RegistryContractGen.cs +++ b/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/RegistryContractGen.cs @@ -1,14 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Schema; using System.ComponentModel.DataAnnotations; -using System.IO; -using System.IO.Compression; -using System.Web.Mvc; - /******************************************** * Consider the following eight combination of input json @@ -96,7 +91,7 @@ protected void MediaInit() string public MediaHash; // Hash of the image of the item so changes can be detected. string public MediaMetadataHash; // Hash of the image of the item so changes can be detected.", 1); - Media_ConstructorParamList = "string _MediaUri, string _MediaHash, string _MediaMetadataHash"; + Media_ConstructorParamList = "string memory _MediaUri, string memory _MediaHash, string memory _MediaMetadataHash"; Media_VarAssignments = addIndentation($@" MediaUri = _MediaUri; @@ -140,7 +135,7 @@ protected void OwnershipInit() string public OwnerDetailHash; //hash of the owner details for the Item, stored off chain ", 1); - Ownership_ConstructorParamList = "address _Owner, string _OwnerDetailHash"; + Ownership_ConstructorParamList = "address _Owner, string memory _OwnerDetailHash"; Ownership_VarAssignments = addIndentation($@" Owner = _Owner; diff --git a/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/SolGen.cs b/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/SolGen.cs index da128c1a..61f5366f 100644 --- a/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/SolGen.cs +++ b/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/SolGen.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Web; namespace PatternCodeGen.CodeGen { @@ -14,10 +13,10 @@ public partial class RegistryContractGen : CodeGen private void SolGenInit() { _ItemStruct = _ItemName + "Struct"; - _propertyCommaList = getPropertyCommaList(true, false, string.Empty); + _propertyCommaList = getPropertyCommaList(true, false, true, string.Empty); } - private string getPropertyCommaList(bool IncludesContractAddress, bool IsIndexOnly, string s, bool EmitType = true, string underscore = "_") + private string getPropertyCommaList(bool IncludesContractAddress, bool IsIndexOnly, bool addMemory, string s, bool EmitType = true, string underscore = "_") { var paramList = new List(); if (!s.Equals(string.Empty, StringComparison.Ordinal)) @@ -31,14 +30,14 @@ private string getPropertyCommaList(bool IncludesContractAddress, bool IsIndexOn ); if (EmitType) { - paramList.AddRange(whereResult.Select(prop => $"{prop.PropertyDataType} {underscore}{prop.PropertyName}")); + paramList.AddRange(whereResult.Select(prop => $"{(addMemory ? potentiallyConvertToMemoryType(prop.PropertyDataType) : prop.PropertyDataType)} {underscore}{prop.PropertyName}")); } else { paramList.AddRange(whereResult.Select(prop => $"{underscore}{prop.PropertyName}")); } - var paramString = string.Join(", ", paramList); - return paramString; + + return string.Join(", ", paramList); } private string PropertyDepenentDeclarations() @@ -78,8 +77,8 @@ private string PropertyDepenentDeclarations() codeString += "\n"; codeString += -$@"event LogNew{_ItemName} ({getPropertyCommaList(true, true, string.Empty)}, uint index); -event LogUpdate{_ItemName} ({getPropertyCommaList(true, true, string.Empty)}, uint index); +$@"event LogNew{_ItemName} ({getPropertyCommaList(true, true, false, string.Empty)}, uint index); +event LogUpdate{_ItemName} ({getPropertyCommaList(true, true, false, string.Empty)}, uint index); "; return addIndentation(codeString, 1); @@ -96,25 +95,30 @@ private string potentiallyConvertToMemoryType(string type) return type; } } + private string IsRegisteredPropertyFunctions() { string codeString = string.Empty; - foreach (var prop in ((RegistryTemplate)inputJSON).Properties) + var properties = ((RegistryTemplate) inputJSON).Properties; + foreach (var prop in properties) { if (prop.IndexType != IndexType_t.PrimaryIndex && prop.IndexType != IndexType_t.Index) continue; codeString += $@"//Lookup to see if a contract address for a {_ItemName} contract is already registered -function isRegistered{_ItemName}{prop.PropertyName}({prop.PropertyDataType} {_ItemName}{prop.PropertyName}) +function isRegistered{_ItemName}{prop.PropertyName}({prop.PropertyDataType} {(prop.PropertyDataType != "address" ? "memory" : "")} {_ItemName}{prop.PropertyName}) public view returns(bool isRegistered) {{ - if({_ItemName}{prop.PropertyName}Index.length == 0) return false; + if ({_ItemName}{prop.PropertyName}Index.length == 0) return false; {potentiallyConvertToMemoryType(prop.PropertyDataType)} var1 = {_ItemName}{prop.PropertyName}Index[{_ItemName}{prop.PropertyName}Lookup[{_ItemName}{prop.PropertyName}].Index]; {potentiallyConvertToMemoryType(prop.PropertyDataType)} var2 = {_ItemName}{prop.PropertyName}; return (keccak256(abi.encodePacked(var1)) == keccak256(abi.encodePacked(var2))); }} "; - codeString += "\n"; + if (prop != properties.Last()) + { + codeString += "\n"; + } } return addIndentation(codeString, 1); @@ -123,10 +127,10 @@ public view private string RegisterFunction() { string codeString = -$@"function Register{_ItemName}({getPropertyCommaList(true, true, string.Empty)}) +$@"function Register{_ItemName}({getPropertyCommaList(true, true, true, string.Empty)}) public {{"; - codeString += + codeString += "\n" + $@" if (isRegistered{_ItemName}{contractAddressPropertyName}(_{contractAddressPropertyName})) revert(); "; @@ -149,7 +153,7 @@ private string RegisterFunction() "; } - string propertyCommaListWithoutType = getPropertyCommaList(true, true, string.Empty, false); + string propertyCommaListWithoutType = getPropertyCommaList(true, true, true, string.Empty, false); propertyCommaListWithoutType += $@", {_ItemName}{contractAddressPropertyName}Lookup[_{contractAddressPropertyName}].Index"; @@ -157,6 +161,7 @@ private string RegisterFunction() $@" emit LogNew{_ItemName}( {addIndentation(propertyCommaListWithoutType, 3)} ); + ContractUpdated(""Register{_ItemName}""); }} "; string Func32ParamList = string.Empty; @@ -179,14 +184,13 @@ private string RegisterFunction() RegisterItemFuncCallArgList += "_" + prop.PropertyName; } } - codeString += + codeString += "\n" + $@"function Register{_ItemName}32({Func32ParamList}) public {{ - return Register{_ItemName} ( + return Register{_ItemName}( {RegisterItemFuncCallArgList}); -}} -"; +}}"; return addIndentation(codeString, 1); } @@ -194,7 +198,8 @@ private string GetItemByPropertyFunctions() { string codeString = string.Empty; string pType, convertion1, convertion2; - foreach (var prop in ((RegistryTemplate)inputJSON).Properties) + var properties = ((RegistryTemplate) inputJSON).Properties; + foreach (var prop in properties) { if (prop.IndexType != IndexType_t.PrimaryIndex && prop.IndexType != IndexType_t.Index || prop.PropertyName == contractAddressPropertyName @@ -221,18 +226,18 @@ private string GetItemByPropertyFunctions() $@" function get{prop.PropertyName}ByAddress(address {_ItemName}{contractAddressPropertyName}) public view -returns({pType} {_ItemName}{prop.PropertyName}) +returns({potentiallyConvertToMemoryType(pType)} {_ItemName}{prop.PropertyName}) {{ - if(!isRegistered{_ItemName}{contractAddressPropertyName}({_ItemName}{contractAddressPropertyName})) revert(); + if (!isRegistered{_ItemName}{contractAddressPropertyName}({_ItemName}{contractAddressPropertyName})) revert(); return {convertion1}({_ItemName}{contractAddressPropertyName}Lookup[{_ItemName}{contractAddressPropertyName}].{prop.PropertyName}); }} -function getAddressBy{prop.PropertyName}({pType} {_ItemName}{prop.PropertyName}) +function getAddressBy{prop.PropertyName}({potentiallyConvertToMemoryType(pType)} {_ItemName}{prop.PropertyName}) public view returns(address {_ItemName}{contractAddressPropertyName}) {{ {potentiallyConvertToMemoryType(prop.PropertyDataType)} idx = {convertion2}({_ItemName}{prop.PropertyName}); - if(!isRegistered{_ItemName}{prop.PropertyName}(idx)) revert(); + if (!isRegistered{_ItemName}{prop.PropertyName}(idx)) revert(); return {_ItemName}{prop.PropertyName}Lookup[idx].{contractAddressPropertyName}; }} "; @@ -257,7 +262,7 @@ public view public view returns({pType} {_ItemName}{prop.PropertyName}) {{ - if(!isRegistered{_ItemName}{contractAddressPropertyName}({_ItemName}{contractAddressPropertyName})) revert(); + if (!isRegistered{_ItemName}{contractAddressPropertyName}({_ItemName}{contractAddressPropertyName})) revert(); return {convertion1}({_ItemName}{contractAddressPropertyName}Lookup[{_ItemName}{contractAddressPropertyName}].{prop.PropertyName}); }} @@ -266,25 +271,55 @@ public view returns(address {_ItemName}{contractAddressPropertyName}) {{ {potentiallyConvertToMemoryType(prop.PropertyDataType)} idx = {convertion2}({_ItemName}{prop.PropertyName}); - if(!isRegistered{_ItemName}{prop.PropertyName}(idx)) revert(); + if (!isRegistered{_ItemName}{prop.PropertyName}(idx)) revert(); return {_ItemName}{prop.PropertyName}Lookup[idx].{contractAddressPropertyName}; -}} -"; +}}"; } + if (prop != properties.Last()) + { + codeString += "\n"; + } } - return addIndentation(codeString, 1); ; + + return addIndentation(codeString, 1); } protected override void SolGen(string outputPath) { string filePath; string outputString = -$@"pragma solidity ^0.4.25; +$@"pragma solidity ^0.5.2; + + import ""./{_ItemContractName}.sol""; -contract {_RegistryContracyName} {{ - enum StateType {{ Created, Open, Closed}} - StateType public State; + + +contract WorkbenchBase {{ + event WorkbenchContractCreated(string applicationName, string workflowName, address originatingAddress); + event WorkbenchContractUpdated(string applicationName, string workflowName, string action, address originatingAddress); + + string internal ApplicationName; + string internal WorkflowName; + + constructor(string memory applicationName, string memory workflowName) internal {{ + ApplicationName = applicationName; + WorkflowName = workflowName; + }} + + function ContractCreated() internal {{ + emit WorkbenchContractCreated(ApplicationName, WorkflowName, msg.sender); + }} + + function ContractUpdated(string memory action) internal {{ + emit WorkbenchContractUpdated(ApplicationName, WorkflowName, action, msg.sender); + }} +}} + + +contract {_RegistryContracyName} is WorkbenchBase(""{_ApplicationName}"", ""{_RegistryContracyName}"") {{ + enum StateType {{ Created, Open, Closed }} + StateType public State; {_ItemStruct}[] public {_ItemName}s; @@ -292,29 +327,31 @@ enum StateType {{ Created, Open, Closed}} string public Description; {PropertyDepenentDeclarations()} - constructor(string _Name, string _Description) public {{ + constructor(string memory _Name, string memory _Description) public {{ Name = _Name; Description = _Description; State = StateType.Created; + ContractCreated(); }} function OpenRegistry() public {{ - State = StateType.Open; + State = StateType.Open; + ContractUpdated(""OpenRegistry""); }} function CloseRegistry() public {{ State = StateType.Closed; + ContractUpdated(""CloseRegistry""); }} {IsRegisteredPropertyFunctions()} {RegisterFunction()} {GetItemByPropertyFunctions()} - function getNumberOfRegistered{_ItemName}s() public - constant + view returns(uint count) {{ return {_ItemName}{contractAddressPropertyName}Index.length; @@ -322,7 +359,7 @@ function CloseRegistry() public function get{_ItemName}AtIndex(uint index) public - constant + view returns(address {_ItemName}{contractAddressPropertyName}) {{ return {_ItemName}{contractAddressPropertyName}Index[index]; @@ -348,10 +385,13 @@ function CloseRegistry() public protected string SolGenItem() { string s = -$@"pragma solidity ^0.4.25; +$@"pragma solidity ^0.5.2; + + import ""./{_ApplicationName}.sol""; -contract {_ItemContractName} {{ + +contract {_ItemContractName} is WorkbenchBase(""{_ApplicationName}"", ""{_ItemContractName}"") {{ // Registry {_RegistryContracyName} My{_ItemName}Registry; @@ -387,9 +427,10 @@ private string RetireFunctionForItem() var codeString = $@" //Retire Function for {_ItemName} -function Retire(string retirementRecordedDateTime) public {{ +function Retire(string memory retirementRecordedDateTime) public {{ RetirementRecordedDateTime = retirementRecordedDateTime; State = StateType.Retired; + ContractUpdated(""Retire""); }} "; return addIndentation(codeString, 1); @@ -421,7 +462,7 @@ private string RegisterFunctionForItem() function {funcName}({argList}) public {{ // only assign if there isn't one assigned already - if (RegistryAddress != 0x0) revert(); + if (RegistryAddress != address(0)) revert(); {ownership_varAssignments} if (State != StateType.Active) revert(); @@ -429,6 +470,7 @@ private string RegisterFunctionForItem() {RegisterItem()} State = StateType.Active; + ContractUpdated(""{funcName}""); }} "; return addIndentation(codeString, 1); @@ -441,8 +483,9 @@ private string AssignRegistryForItem() string output = $@" function AssignRegistry(address _registryAddress) public {{ - if (RegistryAddress != 0x0) revert(); + if (RegistryAddress != address(0)) revert(); RegistryAddress = _registryAddress; + ContractUpdated(""AssignRegistry""); }}"; return addIndentation(output, 1); } @@ -455,6 +498,7 @@ private string AddMediaForItem() function AddMedia({Media_ConstructorParamList}) public {{ {Media_VarAssignments} + ContractUpdated(""AddMedia""); }}"; return addIndentation(output, 1); } @@ -466,13 +510,15 @@ private object ConstructorFunctionForItem() //Constructor Function for {_ItemName} //------------------------------------- "; - var paramString = getPropertyCommaList(false, false, IsRegistryKnown?"string _RegistryAddress":string.Empty); + // TODO: Better to use just 'address' instead of a 'string' + // var paramString = getPropertyCommaList(false, false, true, IsRegistryKnown ? "address _RegistryAddress" : string.Empty); + var paramString = getPropertyCommaList(false, false, true, IsRegistryKnown ? "string memory _RegistryAddress" : string.Empty); string Media_ConstructorParamList_Or_Empty = (MediaSetting.AssociatedMedia == AssociatedMedia_t.SingleElementAtCreation) ? $", {Media_ConstructorParamList}" : string.Empty; string Media_VarAssignments_Or_Empty = (MediaSetting.AssociatedMedia == AssociatedMedia_t.SingleElementAtCreation) ? $"{Media_VarAssignments}" : string.Empty; codeString += $@" -constructor({paramString}{Media_ConstructorParamList_Or_Empty}"; +constructor ({paramString}{Media_ConstructorParamList_Or_Empty}"; if (IsOwnerKnown) codeString += $@", {Ownership_ConstructorParamList}"; codeString += $@") public {{ @@ -493,17 +539,20 @@ private object ConstructorFunctionForItem() "; } codeString += IsRegistryKnown ? $" RegistryAddress = stringToAddress(_RegistryAddress);\n" : string.Empty; + // TODO: Better to use just 'address' instead of a 'string' + // codeString += IsRegistryKnown ? $" RegistryAddress = _RegistryAddress;\n" : string.Empty; if (IsRegistryKnown && (IsOwnerKnown ^ IsOwnershipTypeNone)) { codeString += $@" - My{_ItemName}Registry = {_RegistryContracyName}(RegistryAddress); + My{_ItemName}Registry = {_RegistryContracyName}(RegistryAddress); {RegisterItem()} "; } codeString += -$@"}}"; +$@" ContractCreated(); +}}"; return addIndentation(codeString,1); } diff --git a/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/UtilsGen.cs b/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/UtilsGen.cs index 05378854..bbec79e1 100644 --- a/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/UtilsGen.cs +++ b/accelerators/registry-generator/PatternCodeGen/CodeGen/Registry/UtilsGen.cs @@ -1,18 +1,12 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Web; - -namespace PatternCodeGen.CodeGen +namespace PatternCodeGen.CodeGen { public partial class RegistryContractGen : CodeGen { public string UtilsGen() { return -$@" /******************* Utils functions *******************************************/ - function stringToBytes32(string memory source) pure public returns (bytes32 result) {{ +$@" /******************* Utils functions *******************************************/ + function stringToBytes32(string memory source) public pure returns (bytes32 result) {{ bytes memory tempEmptyStringTest = bytes(source); if (tempEmptyStringTest.length == 0) {{ return 0x0; @@ -23,7 +17,7 @@ function stringToBytes32(string memory source) pure public returns (bytes32 res }} }} - function bytes32ToString (bytes32 x) pure public returns (string) {{ + function bytes32ToString (bytes32 x) public pure returns (string memory result) {{ bytes memory bytesString = new bytes(32); uint charCount = 0; for (uint j = 0; j < 32; j++) {{ @@ -34,27 +28,38 @@ function bytes32ToString (bytes32 x) pure public returns (string) {{ }} }} bytes memory bytesStringTrimmed = new bytes(charCount); - for (j = 0; j < charCount; j++) {{ + for (uint j = 0; j < charCount; j++) {{ bytesStringTrimmed[j] = bytesString[j]; }} - return string(bytesStringTrimmed); + return string(bytesStringTrimmed); }} - function stringToAddress(string _a) pure public returns (address){{ + function stringToAddress(string memory _a) public pure returns (address _parsedAddress) {{ bytes memory tmp = bytes(_a); uint160 iaddr = 0; uint160 b1; uint160 b2; - for (uint i=2; i<2+2*20; i+=2) - {{ + for (uint i = 2; i < 2 + 2 * 20; i += 2) {{ iaddr *= 256; - b1 = uint160(tmp[i]); - b2 = uint160(tmp[i+1]); - if ((b1 >= 97)&&(b1 <= 102)) b1 -= 87; - else if ((b1 >= 48)&&(b1 <= 57)) b1 -= 48; - if ((b2 >= 97)&&(b2 <= 102)) b2 -= 87; - else if ((b2 >= 48)&&(b2 <= 57)) b2 -= 48; - iaddr += (b1*16+b2); + b1 = uint160(uint8(tmp[i])); + b2 = uint160(uint8(tmp[i + 1])); + + if ((b1 >= 97) && (b1 <= 102)) {{ + b1 -= 87; + }} else if ((b1 >= 65) && (b1 <= 70)) {{ + b1 -= 55; + }} else if ((b1 >= 48) && (b1 <= 57)) {{ + b1 -= 48; + }} + + if ((b2 >= 97) && (b2 <= 102)) {{ + b2 -= 87; + }} else if ((b2 >= 65) && (b2 <= 70)) {{ + b2 -= 55; + }} else if ((b2 >= 48) && (b2 <= 57)) {{ + b2 -= 48; + }} + iaddr += (b1 * 16 + b2); }} return address(iaddr); }} diff --git a/accelerators/registry-generator/PatternCodeGen/PatternCodeGen.csproj b/accelerators/registry-generator/PatternCodeGen/PatternCodeGen.csproj index 5e275301..565af6cd 100644 --- a/accelerators/registry-generator/PatternCodeGen/PatternCodeGen.csproj +++ b/accelerators/registry-generator/PatternCodeGen/PatternCodeGen.csproj @@ -258,13 +258,6 @@ - - - - - - -