mirror of https://github.com/hyperledger/besu
[PAN-2789] Add EthSigner acceptance test (#1892)
Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>pull/2/head
parent
cb6338f497
commit
8747092586
@ -0,0 +1,107 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner; |
||||
|
||||
import java.io.IOException; |
||||
import java.math.BigInteger; |
||||
import java.net.URI; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.apache.logging.log4j.LogManager; |
||||
import org.apache.logging.log4j.Logger; |
||||
import org.web3j.protocol.Web3jService; |
||||
import org.web3j.protocol.core.Request; |
||||
import org.web3j.protocol.core.methods.request.Transaction; |
||||
import org.web3j.protocol.core.methods.response.EthSendTransaction; |
||||
import org.web3j.protocol.eea.Eea; |
||||
import org.web3j.protocol.http.HttpService; |
||||
|
||||
public class EthSignerClient { |
||||
private static final Logger LOG = LogManager.getLogger(); |
||||
private final Web3jService web3jService; |
||||
private final Eea web3j; |
||||
private final String from; |
||||
|
||||
public EthSignerClient(final URI ethSignerUri) throws IOException { |
||||
this.web3jService = new HttpService(ethSignerUri.toString()); |
||||
this.web3j = Eea.build(web3jService); |
||||
this.from = resolveFrom(ethSignerUri); |
||||
} |
||||
|
||||
private String resolveFrom(final URI ethSignerUri) throws IOException { |
||||
final List<String> accounts; |
||||
try { |
||||
accounts = ethAccounts(); |
||||
return accounts.get(0); |
||||
} catch (IOException e) { |
||||
LOG.info("Failed to connect to EthSigner at {}", ethSignerUri); |
||||
throw e; |
||||
} catch (Exception e) { |
||||
LOG.info("Falling back to signing with node key"); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public List<String> ethAccounts() throws IOException { |
||||
return web3j.ethAccounts().send().getAccounts(); |
||||
} |
||||
|
||||
public String ethSendTransaction( |
||||
final String to, |
||||
final BigInteger gas, |
||||
final BigInteger gasPrice, |
||||
final BigInteger value, |
||||
final String data, |
||||
final BigInteger nonce) |
||||
throws IOException { |
||||
return web3j |
||||
.ethSendTransaction(new Transaction(from, nonce, gasPrice, gas, to, value, data)) |
||||
.send() |
||||
.getTransactionHash(); |
||||
} |
||||
|
||||
public String eeaSendTransaction( |
||||
final String to, |
||||
final BigInteger gas, |
||||
final BigInteger gasPrice, |
||||
final String data, |
||||
final BigInteger nonce, |
||||
final String privateFrom, |
||||
final List<String> privateFor, |
||||
final String restriction) |
||||
throws IOException { |
||||
|
||||
final PrivateTransactionRequest transaction = |
||||
new PrivateTransactionRequest( |
||||
from, |
||||
nonce, |
||||
gasPrice, |
||||
gas, |
||||
to, |
||||
BigInteger.ZERO, |
||||
data, |
||||
privateFrom, |
||||
privateFor, |
||||
restriction); |
||||
|
||||
// temporary until implemented in web3j
|
||||
return new Request<>( |
||||
"eea_sendTransaction", |
||||
Collections.singletonList(transaction), |
||||
web3jService, |
||||
EthSendTransaction.class) |
||||
.send() |
||||
.getTransactionHash(); |
||||
} |
||||
} |
@ -0,0 +1,109 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner; |
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; |
||||
import static com.github.tomakehurst.wiremock.client.WireMock.post; |
||||
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; |
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; |
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
import tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner.testutil.EthSignerTestHarness; |
||||
import tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner.testutil.EthSignerTestHarnessFactory; |
||||
|
||||
import java.io.IOException; |
||||
import java.math.BigInteger; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import com.github.tomakehurst.wiremock.junit.WireMockRule; |
||||
import org.junit.BeforeClass; |
||||
import org.junit.ClassRule; |
||||
import org.junit.Test; |
||||
import org.junit.rules.TemporaryFolder; |
||||
|
||||
public class EthSignerClientTest { |
||||
@ClassRule public static final TemporaryFolder folder = new TemporaryFolder(); |
||||
|
||||
@ClassRule |
||||
public static final WireMockRule wireMockRule = |
||||
new WireMockRule(wireMockConfig().dynamicPort().dynamicPort()); |
||||
|
||||
private static final String MOCK_RESPONSE = "mock_transaction_hash"; |
||||
private static final String MOCK_SEND_TRANSACTION_RESPONSE = |
||||
"{\n" |
||||
+ " \"id\":67,\n" |
||||
+ " \"jsonrpc\":\"2.0\",\n" |
||||
+ " \"result\": \"" |
||||
+ MOCK_RESPONSE |
||||
+ "\"\n" |
||||
+ "}"; |
||||
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; |
||||
|
||||
private static EthSignerClient ethSignerClient; |
||||
|
||||
private static EthSignerTestHarness testHarness; |
||||
|
||||
@BeforeClass |
||||
public static void setUpOnce() throws Exception { |
||||
stubFor(post("/").willReturn(aResponse().withBody(MOCK_SEND_TRANSACTION_RESPONSE))); |
||||
|
||||
folder.create(); |
||||
|
||||
testHarness = |
||||
EthSignerTestHarnessFactory.create( |
||||
folder.newFolder().toPath(), |
||||
"ethSignerKey--fe3b557e8fb62b89f4916b721be55ceb828dbd73.json", |
||||
wireMockRule.port(), |
||||
2018); |
||||
|
||||
ethSignerClient = new EthSignerClient(testHarness.getHttpListeningUrl()); |
||||
} |
||||
|
||||
@Test |
||||
public void testEthAccounts() throws IOException { |
||||
final List<String> accounts = ethSignerClient.ethAccounts(); |
||||
assertEquals(1, accounts.size()); |
||||
assertEquals("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", accounts.get(0)); |
||||
} |
||||
|
||||
@Test |
||||
public void testEthSendTransaction() throws IOException { |
||||
final String response = |
||||
ethSignerClient.ethSendTransaction( |
||||
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", |
||||
BigInteger.ZERO, |
||||
BigInteger.ZERO, |
||||
BigInteger.ZERO, |
||||
"", |
||||
BigInteger.ZERO); |
||||
|
||||
assertEquals(MOCK_RESPONSE, response); |
||||
} |
||||
|
||||
@Test |
||||
public void testEeaSendTransaction() throws IOException { |
||||
final String response = |
||||
ethSignerClient.eeaSendTransaction( |
||||
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", |
||||
BigInteger.ZERO, |
||||
BigInteger.ZERO, |
||||
"", |
||||
BigInteger.ZERO, |
||||
ENCLAVE_PUBLIC_KEY, |
||||
Collections.emptyList(), |
||||
""); |
||||
|
||||
assertEquals(MOCK_RESPONSE, response); |
||||
} |
||||
} |
@ -0,0 +1,101 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.util.List; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
import org.web3j.utils.Numeric; |
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||
public class PrivateTransactionRequest { |
||||
|
||||
private final String from; |
||||
private final BigInteger nonce; |
||||
private final BigInteger gasPrice; |
||||
private final BigInteger gas; |
||||
private final String to; |
||||
private final BigInteger value; |
||||
private final String data; |
||||
private final String privateFrom; |
||||
private final List<String> privateFor; |
||||
private final String restriction; |
||||
|
||||
public PrivateTransactionRequest( |
||||
final String from, |
||||
final BigInteger nonce, |
||||
final BigInteger gasPrice, |
||||
final BigInteger gasLimit, |
||||
final String to, |
||||
final BigInteger value, |
||||
final String data, |
||||
final String privateFrom, |
||||
final List<String> privateFor, |
||||
final String restriction) { |
||||
this.from = from; |
||||
this.to = to; |
||||
this.gas = gasLimit; |
||||
this.gasPrice = gasPrice; |
||||
this.value = value; |
||||
this.data = data == null ? null : Numeric.prependHexPrefix(data); |
||||
this.nonce = nonce; |
||||
this.privateFrom = privateFrom; |
||||
this.privateFor = privateFor; |
||||
this.restriction = restriction; |
||||
} |
||||
|
||||
public String getFrom() { |
||||
return from; |
||||
} |
||||
|
||||
public String getTo() { |
||||
return to; |
||||
} |
||||
|
||||
public String getGas() { |
||||
return convert(gas); |
||||
} |
||||
|
||||
public String getGasPrice() { |
||||
return convert(gasPrice); |
||||
} |
||||
|
||||
public String getValue() { |
||||
return convert(value); |
||||
} |
||||
|
||||
public String getData() { |
||||
return data; |
||||
} |
||||
|
||||
public String getNonce() { |
||||
return convert(nonce); |
||||
} |
||||
|
||||
private String convert(final BigInteger value) { |
||||
return value == null ? null : Numeric.encodeQuantity(value); |
||||
} |
||||
|
||||
public String getPrivateFrom() { |
||||
return privateFrom; |
||||
} |
||||
|
||||
public List<String> getPrivateFor() { |
||||
return privateFor; |
||||
} |
||||
|
||||
public String getRestriction() { |
||||
return restriction; |
||||
} |
||||
} |
@ -0,0 +1,93 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner.testutil; |
||||
|
||||
import tech.pegasys.ethsigner.core.Config; |
||||
import tech.pegasys.ethsigner.core.signing.ChainIdProvider; |
||||
|
||||
import java.net.InetAddress; |
||||
import java.nio.file.Path; |
||||
import java.time.Duration; |
||||
|
||||
import org.apache.logging.log4j.Level; |
||||
|
||||
public class EthSignerConfig implements Config { |
||||
private final Level logLevel; |
||||
private final InetAddress downstreamHttpHost; |
||||
private final Integer downStreamHttpPort; |
||||
private Duration downstreamHttpRequestTimeout; |
||||
private final InetAddress httpListenHost; |
||||
private final Integer httpListenPort; |
||||
private final ChainIdProvider chainId; |
||||
private final Path dataDirectory; |
||||
|
||||
public EthSignerConfig( |
||||
final Level logLevel, |
||||
final InetAddress downstreamHttpHost, |
||||
final Integer downStreamHttpPort, |
||||
final Duration downstreamHttpRequestTimeout, |
||||
final InetAddress httpListenHost, |
||||
final Integer httpListenPort, |
||||
final ChainIdProvider chainId, |
||||
final Path dataDirectory) { |
||||
|
||||
this.logLevel = logLevel; |
||||
this.downstreamHttpHost = downstreamHttpHost; |
||||
this.downStreamHttpPort = downStreamHttpPort; |
||||
this.downstreamHttpRequestTimeout = downstreamHttpRequestTimeout; |
||||
this.httpListenHost = httpListenHost; |
||||
this.httpListenPort = httpListenPort; |
||||
this.chainId = chainId; |
||||
this.dataDirectory = dataDirectory; |
||||
} |
||||
|
||||
@Override |
||||
public Level getLogLevel() { |
||||
return logLevel; |
||||
} |
||||
|
||||
@Override |
||||
public InetAddress getDownstreamHttpHost() { |
||||
return downstreamHttpHost; |
||||
} |
||||
|
||||
@Override |
||||
public Integer getDownstreamHttpPort() { |
||||
return downStreamHttpPort; |
||||
} |
||||
|
||||
@Override |
||||
public Duration getDownstreamHttpRequestTimeout() { |
||||
return downstreamHttpRequestTimeout; |
||||
} |
||||
|
||||
@Override |
||||
public InetAddress getHttpListenHost() { |
||||
return httpListenHost; |
||||
} |
||||
|
||||
@Override |
||||
public Integer getHttpListenPort() { |
||||
return httpListenPort; |
||||
} |
||||
|
||||
@Override |
||||
public ChainIdProvider getChainId() { |
||||
return chainId; |
||||
} |
||||
|
||||
@Override |
||||
public Path getDataPath() { |
||||
return dataDirectory; |
||||
} |
||||
} |
@ -0,0 +1,34 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner.testutil; |
||||
|
||||
import java.net.URI; |
||||
import java.util.Properties; |
||||
|
||||
public class EthSignerTestHarness { |
||||
private final EthSignerConfig config; |
||||
private final Properties portsProperties; |
||||
|
||||
public EthSignerTestHarness(final EthSignerConfig config, final Properties properties) { |
||||
this.config = config; |
||||
this.portsProperties = properties; |
||||
} |
||||
|
||||
public URI getHttpListeningUrl() { |
||||
return URI.create( |
||||
"http://" |
||||
+ config.getHttpListenHost().getHostAddress() |
||||
+ ":" |
||||
+ portsProperties.getProperty("http-jsonrpc")); |
||||
} |
||||
} |
@ -0,0 +1,101 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner.testutil; |
||||
|
||||
import static net.consensys.cava.io.file.Files.copyResource; |
||||
|
||||
import tech.pegasys.ethsigner.core.EthSigner; |
||||
import tech.pegasys.ethsigner.core.signing.ConfigurationChainId; |
||||
import tech.pegasys.ethsigner.signer.filebased.CredentialTransactionSigner; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.IOException; |
||||
import java.net.InetAddress; |
||||
import java.nio.file.Files; |
||||
import java.nio.file.Path; |
||||
import java.time.Duration; |
||||
import java.util.Properties; |
||||
import java.util.concurrent.TimeUnit; |
||||
import java.util.stream.Stream; |
||||
|
||||
import org.apache.logging.log4j.Level; |
||||
import org.apache.logging.log4j.LogManager; |
||||
import org.apache.logging.log4j.Logger; |
||||
import org.awaitility.Awaitility; |
||||
import org.web3j.crypto.CipherException; |
||||
import org.web3j.crypto.WalletUtils; |
||||
|
||||
public class EthSignerTestHarnessFactory { |
||||
|
||||
private static final Logger LOG = LogManager.getLogger(); |
||||
private static final String HOST = "127.0.0.1"; |
||||
|
||||
public static EthSignerTestHarness create( |
||||
final Path tempDir, final String keyPath, final Integer pantheonPort, final long chainId) |
||||
throws IOException, CipherException { |
||||
|
||||
final Path keyFilePath = copyResource(keyPath, tempDir.resolve(keyPath)); |
||||
|
||||
final EthSignerConfig config = |
||||
new EthSignerConfig( |
||||
Level.DEBUG, |
||||
InetAddress.getByName(HOST), |
||||
pantheonPort, |
||||
Duration.ofSeconds(10), |
||||
InetAddress.getByName(HOST), |
||||
0, |
||||
new ConfigurationChainId(chainId), |
||||
tempDir); |
||||
|
||||
final EthSigner ethSigner = |
||||
new EthSigner( |
||||
config, |
||||
new CredentialTransactionSigner( |
||||
WalletUtils.loadCredentials("", keyFilePath.toAbsolutePath().toFile()))); |
||||
ethSigner.run(); |
||||
|
||||
waitForPortFile(tempDir); |
||||
|
||||
LOG.info("EthSigner port: {}", config.getHttpListenPort()); |
||||
|
||||
return new EthSignerTestHarness(config, loadPortsFile(tempDir)); |
||||
} |
||||
|
||||
private static Properties loadPortsFile(final Path tempDir) { |
||||
final Properties portsProperties = new Properties(); |
||||
try (final FileInputStream fis = |
||||
new FileInputStream(new File(tempDir.toFile(), "ethsigner.ports"))) { |
||||
portsProperties.load(fis); |
||||
LOG.info("Ports for ethsigner {}", portsProperties); |
||||
} catch (final IOException e) { |
||||
throw new RuntimeException("Error reading EthSigner ports file", e); |
||||
} |
||||
return portsProperties; |
||||
} |
||||
|
||||
private static void waitForPortFile(final Path tempDir) { |
||||
final File file = new File(tempDir.toFile(), "ethsigner.ports"); |
||||
Awaitility.waitAtMost(30, TimeUnit.SECONDS) |
||||
.until( |
||||
() -> { |
||||
if (file.exists()) { |
||||
try (final Stream<String> s = Files.lines(file.toPath())) { |
||||
return s.count() > 0; |
||||
} |
||||
} else { |
||||
return false; |
||||
} |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,80 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.tests.web3j.privacy; |
||||
|
||||
import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.PrivateTransactionBuilder.EVENT_EMITTER_CONSTRUCTOR; |
||||
import static tech.pegasys.pantheon.tests.web3j.privacy.PrivacyGroup.generatePrivacyGroup; |
||||
|
||||
import tech.pegasys.pantheon.ethereum.core.Address; |
||||
import tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner.EthSignerClient; |
||||
import tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner.testutil.EthSignerTestHarness; |
||||
import tech.pegasys.pantheon.tests.acceptance.dsl.ethsigner.testutil.EthSignerTestHarnessFactory; |
||||
import tech.pegasys.pantheon.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase; |
||||
import tech.pegasys.pantheon.tests.acceptance.dsl.privacy.PrivacyNet; |
||||
import tech.pegasys.pantheon.util.bytes.BytesValue; |
||||
|
||||
import java.io.IOException; |
||||
import java.math.BigInteger; |
||||
import java.util.Collections; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
public class EthSignerAcceptanceTest extends PrivacyAcceptanceTestBase { |
||||
private PrivacyNet privacyNet; |
||||
|
||||
private EthSignerClient ethSignerClient; |
||||
|
||||
@Before |
||||
public void setUp() throws Exception { |
||||
privacyNet = |
||||
PrivacyNet.builder(privacy, privacyPantheon, cluster, false).addMinerNode("Alice").build(); |
||||
privacyNet.startPrivacyNet(); |
||||
|
||||
final EthSignerTestHarness ethSigner = |
||||
EthSignerTestHarnessFactory.create( |
||||
privacy.newFolder().toPath(), |
||||
"ethSignerKey--fe3b557e8fb62b89f4916b721be55ceb828dbd73.json", |
||||
privacyNet.getNode("Alice").getJsonRpcSocketPort().orElseThrow(), |
||||
2018); |
||||
ethSignerClient = new EthSignerClient(ethSigner.getHttpListeningUrl()); |
||||
} |
||||
|
||||
@Test |
||||
public void privateSmartContractMustDeploy() throws IOException { |
||||
final BytesValue privacyGroupId = generatePrivacyGroup(privacyNet, "Alice"); |
||||
final long nonce = privacyNet.getNode("Alice").nextNonce(privacyGroupId); |
||||
|
||||
final String transactionHash = |
||||
ethSignerClient.eeaSendTransaction( |
||||
null, |
||||
BigInteger.valueOf(63992), |
||||
BigInteger.valueOf(1000), |
||||
EVENT_EMITTER_CONSTRUCTOR.toString(), |
||||
BigInteger.valueOf(nonce), |
||||
privacyNet.getEnclave("Alice").getPublicKeys().get(0), |
||||
Collections.emptyList(), |
||||
"restricted"); |
||||
|
||||
privacyNet.getNode("Alice").verify(eea.expectSuccessfulTransactionReceipt(transactionHash)); |
||||
|
||||
final String expectedContractAddress = |
||||
Address.privateContractAddress( |
||||
privacyNet.getNode("Alice").getAddress(), nonce, privacyGroupId) |
||||
.toString(); |
||||
|
||||
privateTransactionVerifier |
||||
.validPrivateContractDeployed(expectedContractAddress) |
||||
.verify(privacyNet.getNode("Alice"), transactionHash); |
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
{"address":"fe3b557e8fb62b89f4916b721be55ceb828dbd73","id":"004bac44-2955-40bf-8b1f-5376f428644f","version":3,"crypto":{"cipher":"aes-128-ctr","ciphertext":"28e23ffb25d1ef6a665a5a61866f353c2640b2ec55bd080f557ac4da8c8ba1d1","cipherparams":{"iv":"07bf8e210d7fbb5c4731ac15388a7939"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"8d454299a7ac29cbcd8817a8d1f12723592421d3e0a8bc56aff4719bf78bcec9"},"mac":"9073b2a8f454b0942b9350da96b1431e15edfdddb796ece0ab3fc6e14ca18190"}} |
Loading…
Reference in new issue