From 0a86152ac5789fb260c508f2586403177af322ab Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:36:13 +0800 Subject: [PATCH] (contract): add merge abi logic, support merge 'as' and 'from' import, add event sample contracts. (#855) --- .circleci/config.yml | 5 +- .../java/console/common/ConsoleUtils.java | 11 +++- .../console/contract/ConsoleContractImpl.java | 17 ++++-- .../contract/utils/ContractCompiler.java | 56 ++++++++++++++++--- .../resources/contract/solidity/BaseEvent.sol | 20 +++++++ .../resources/contract/solidity/EchoEvent.sol | 51 +++++++++++++++++ 6 files changed, 145 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/contract/solidity/BaseEvent.sol create mode 100644 src/main/resources/contract/solidity/EchoEvent.sol diff --git a/.circleci/config.yml b/.circleci/config.yml index ba07a3f9..14882f63 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,10 @@ jobs: - run: name: Setup dependencies command: | - yum install -y epel-release centos-release-scl which python python-devel + cd /etc/yum.repos.d/ + sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* + sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* + yum update -y yum install -y git openssl-devel openssl java java-devel - checkout - run: diff --git a/src/main/java/console/common/ConsoleUtils.java b/src/main/java/console/common/ConsoleUtils.java index 6ed682b7..9164bda2 100644 --- a/src/main/java/console/common/ConsoleUtils.java +++ b/src/main/java/console/common/ConsoleUtils.java @@ -1058,6 +1058,15 @@ public static void main(String[] args) { } public static Version convertStringToVersion(String version) { - return Version.valueOf("V" + version.replace('.', '_')); + try { + return Version.valueOf("V" + version.replace('.', '_')); + } catch (Exception e) { + System.out.println( + "Invalid solidity version: " + + version + + ", only support: " + + Arrays.toString(Version.values())); + throw e; + } } } diff --git a/src/main/java/console/contract/ConsoleContractImpl.java b/src/main/java/console/contract/ConsoleContractImpl.java index 864b01de..6a23e106 100644 --- a/src/main/java/console/contract/ConsoleContractImpl.java +++ b/src/main/java/console/contract/ConsoleContractImpl.java @@ -1,5 +1,7 @@ package console.contract; +import static console.contract.utils.ContractCompiler.mergeAbi; +import static console.contract.utils.ContractCompiler.mergeSource; import static org.fisco.solc.compiler.SolidityCompiler.Options.ABI; import static org.fisco.solc.compiler.SolidityCompiler.Options.BIN; import static org.fisco.solc.compiler.SolidityCompiler.Options.METADATA; @@ -30,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -1073,27 +1076,30 @@ private String getSolidityAbi(String contractFileName) throws Exception { if (!solFile.exists()) { throw new Exception("The contract file " + contractFilePath + " doesn't exist!"); } - String contractName = solFile.getName().split("\\.")[0]; List defaultOptions = Arrays.asList(ABI, BIN, METADATA); List options = new ArrayList<>(defaultOptions); logger.debug( "compileSolToBinAndAbi, solc version:{} ,basePath: {}", - Version.V0_8_11, + Version.V0_8_26, solFile.getParentFile().getCanonicalPath()); SolidityCompiler.Option basePath = new SolidityCompiler.CustomOption( "base-path", solFile.getParentFile().getCanonicalPath()); options.add(basePath); + String fileName = solFile.getName(); + String dir = solFile.getParentFile().getCanonicalPath() + File.separator; + + String mergedSource = mergeSource(dir, fileName, new HashSet<>()); // compile ecdsa SolidityCompiler.Result res = SolidityCompiler.compile( - solFile, + mergedSource.getBytes(StandardCharsets.UTF_8), (client.getCryptoType() == CryptoType.SM_TYPE), true, - Version.V0_8_11, + Version.V0_8_26, options.toArray(new SolidityCompiler.Option[0])); if (logger.isDebugEnabled()) { @@ -1111,8 +1117,7 @@ private String getSolidityAbi(String contractFileName) throws Exception { } CompilationResult result = CompilationResult.parse(res.getOutput()); - CompilationResult.ContractMetadata contractMetadata = result.getContract(contractName); - return contractMetadata.abi; + return mergeAbi(result); } private String getWasmAbi(String groupId, String pwd, String contractFileName) diff --git a/src/main/java/console/contract/utils/ContractCompiler.java b/src/main/java/console/contract/utils/ContractCompiler.java index 9019966d..b11f4aa9 100644 --- a/src/main/java/console/contract/utils/ContractCompiler.java +++ b/src/main/java/console/contract/utils/ContractCompiler.java @@ -20,6 +20,10 @@ import static org.fisco.solc.compiler.SolidityCompiler.Options.METADATA; import static org.fisco.solc.compiler.SolidityCompiler.Options.USERDOC; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.node.ArrayNode; import console.common.ConsoleUtils; import console.contract.exceptions.CompileContractException; import console.contract.model.AbiAndBin; @@ -38,6 +42,7 @@ import org.apache.commons.io.FileUtils; import org.fisco.bcos.codegen.v3.exceptions.CodeGenException; import org.fisco.bcos.codegen.v3.utils.CodeGenUtils; +import org.fisco.bcos.sdk.v3.utils.ObjectMapperFactory; import org.fisco.bcos.sdk.v3.utils.StringUtils; import org.fisco.evm.analysis.EvmAnalyser; import org.fisco.solc.compiler.CompilationResult; @@ -241,7 +246,8 @@ public static AbiAndBin compileSolToBinAndAbi( String bin = sm ? "" : meta.bin; String smBin = sm ? meta.bin : ""; - AbiAndBin abiAndBin = new AbiAndBin(meta.abi, bin, smBin, meta.devdoc); + String abi = mergeAbi(result); + AbiAndBin abiAndBin = new AbiAndBin(abi, bin, smBin, meta.devdoc); // evm static analysis File abiFile = new File(abiDir + contractName + ".abi"); @@ -268,8 +274,11 @@ public static AbiAndBin compileSolToBinAndAbi( } } - String abi = FileUtils.readFileToString(abiFile, StandardCharsets.UTF_8); - abiAndBin.setAbi(abi); + // write abi and re-read abi for add evm analysis result + if (isContractParallelAnalysis) { + abi = FileUtils.readFileToString(abiFile, StandardCharsets.UTF_8); + abiAndBin.setAbi(abi); + } checkBinaryCode(contractName, meta.bin); return abiAndBin; } @@ -287,7 +296,10 @@ public static String mergeSource(String currentDir, String sourceFile, Set contractNames = result.getContractKeys(); + if (contractNames.isEmpty()) { + return null; + } + ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + ArrayNode mainNode = (ArrayNode) objectReader.createArrayNode(); + for (String contractName : contractNames) { + String key = contractName.substring(contractName.lastIndexOf(':') + 1); + JsonNode jsonNode = objectReader.readTree(result.getContract(key).abi); + if (jsonNode.isArray() && !jsonNode.isEmpty()) { + mainNode.addAll((ArrayNode) jsonNode); + } + } + return mainNode.toString(); + } + public static void checkBinaryCode(String contractName, String binary) throws CompileContractException { String externalLibSplitter = "_"; diff --git a/src/main/resources/contract/solidity/BaseEvent.sol b/src/main/resources/contract/solidity/BaseEvent.sol new file mode 100644 index 00000000..5252b50a --- /dev/null +++ b/src/main/resources/contract/solidity/BaseEvent.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <=0.8.26; + +contract BaseEvent { + + //--------------------------------------------------------------------------------------------------------------- + event Transfer(string indexed from_account, string indexed to_account, uint256 indexed amount); + event TransferAccount(string indexed from_account,string indexed to_account); + event TransferAmount(uint256 indexed amount); + + function transfer(string memory from_account, string memory to_account, uint256 amount) public { + + emit Transfer(from_account, to_account, amount); + + emit TransferAccount(from_account, to_account); + + emit TransferAmount(amount); + + } +} diff --git a/src/main/resources/contract/solidity/EchoEvent.sol b/src/main/resources/contract/solidity/EchoEvent.sol new file mode 100644 index 00000000..cdbfae12 --- /dev/null +++ b/src/main/resources/contract/solidity/EchoEvent.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <=0.8.26; + +contract BaseEvent { + + //--------------------------------------------------------------------------------------------------------------- + event Transfer(string indexed from_account, string indexed to_account, uint256 indexed amount); + event TransferAccount(string indexed from_account,string indexed to_account); + event TransferAmount(uint256 indexed amount); + + function transfer(string memory from_account, string memory to_account, uint256 amount) public { + + emit Transfer(from_account, to_account, amount); + + emit TransferAccount(from_account, to_account); + + emit TransferAmount(amount); + + } +} + +contract EchoEvent { + + event Echo1(uint256 indexed u); + event Echo2(int256 indexed i); + event Echo3(string indexed s); + event Echo4(uint256 indexed u, int256 indexed i, string indexed s); + + function echo(uint256 u, int256 i, string memory s) public returns(uint256, int256, string memory) { + + emit Echo1(u); + emit Echo2(i); + emit Echo3(s); + emit Echo4(u, i ,s); + + return (u, i , s); + } + + event Echo5(bytes32 indexed bsn); + event Echo6(bytes indexed bs); + event Echo7(bytes32 indexed bsn, bytes indexed bs); + + function echo(bytes32 bsn, bytes memory bs) public returns(bytes32, bytes memory) { + + emit Echo5(bsn); + emit Echo6(bs); + emit Echo7(bsn, bs); + + return (bsn, bs); + } +}