Skip to content

Commit 8037936

Browse files
authored
Support new CIP37 address (#18)
* supplyInfo add new field totalCirculate * refactor Address type * refactor address type from String to Address * update readme and changelog
1 parent 9cb5ef5 commit 8037936

40 files changed

Lines changed: 999 additions & 540 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ gradle-app.setting
3232
.settings/
3333
bin
3434
.idea
35-
todo.md
35+
docs/cfx-address.md
36+
docs/tmp.md

CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
### 1.0.0
2+
3+
1. Class Address support new CIP37 address
4+
2. Where ever need an address, you should pass an `Address` instance, String address will not work
5+
3. `getStatus` return a new field `networkId`
6+
4. `getSupplyInfo` return a new field `totalCirculating`
7+
5. `Address.validate` has been moved to `AddressType.validateHexAddress`
8+
6. ERC20Call, ERC20Executor, ERC777Call, ERC777Executor has been removed, you can use the new ERC20, ERC777
9+
7. AccountManager's constructor add a new parameter `networkId`
110

211

312
### 0.9.0
@@ -6,4 +15,5 @@
615
2. Add new RPC methods: cfx_getDepositList, cfx_getVoteList, cfx_getSupplyInfo
716
3. Add support for InternalContracts
817
4. Merge ERC20, ERC777 call and executor
9-
5. Update default gasPrice to 1 Drip
18+
5. Update default gasPrice to 1 Drip
19+
6. Update RawTransaction default chainId to 1029(mainnet)

README.md

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,27 @@ The Conflux Java SDK allows any Java client to interact with a local or remote C
55
## Docs
66

77
* [API](https://conflux-chain.github.io/java-conflux-sdk/index.html)
8+
* [changelog](./CHANGELOG.md)
89

10+
## Conflux Address
11+
Conflux import a new base32 address at [CIP37](https://github.com/Conflux-Chain/CIPs/blob/master/CIPs/cip-37.md).
12+
From `conflux-rust` v1.1.1, and `java-conflux-sdk` 1.0, the new CIP37 will be supported.
13+
The `Address` class has added support for CIP37 address.
14+
15+
```java
16+
int testNetId = 1; // mainnet is 1029
17+
Address a = new Address("0x13d2bA4eD43542e7c54fbB6c5fCCb9f269C1f94C", testNetId);
18+
Address b = new Address("cfxtest:aak7fsws4u4yf38fk870218p1h3gxut3ku00u1k1da");
19+
20+
a.getAddress(); // "cfxtest:aak7fsws4u4yf38fk870218p1h3gxut3ku00u1k1da"
21+
a.getHexAddress(); // "0x13d2bA4eD43542e7c54fbB6c5fCCb9f269C1f94C"
22+
a.getVerboseAddress(); // "NET1921:TYPE.USER:AAR8JZYBZV0FHZREAV49SYXNZUT8S0JT1AT8UHK7M3"
23+
a.getNetworkId(); // 1
24+
a.getType(); // user
25+
```
26+
27+
For complete CIP37 address updates [check here](./docs/cfx-address.md)
28+
Note: `java-conflux-sdk` `v1.0` is an incompatible version, it only work with `conflux-rust` `1.1.1 or above`.
929

1030
## Manage Accounts
1131
Use `AccountManager` to manage accounts at local machine.
@@ -35,11 +55,11 @@ public class App {
3555

3656
- Sign a transaction with unlocked account:
3757
```java
38-
AccountManager.signTransaction(RawTransaction tx, String address)
58+
AccountManager.signTransaction(RawTransaction tx, Address address)
3959
```
4060
- Sign a transaction with passphrase for locked account:
4161
```java
42-
AccountManager.signTransaction(RawTransaction tx, String address, String password)
62+
AccountManager.signTransaction(RawTransaction tx, Address address, String password)
4363
```
4464

4565

@@ -72,7 +92,7 @@ To send a transaction, first you need to build a transaction and sign the transa
7292
BigInteger value = new BigInteger("1000", 16);
7393
TransactionBuilder txBuilder = new TransactionBuilder("0x-the-sender-address");
7494
txBuilder.withChainId(1);
75-
txBuilder.withTo("0x13d2bA4eD43542e7c54fbB6c5fCCb9f269C1f94C");
95+
txBuilder.withTo(new Address("cfxtest:aak7fsws4u4yf38fk870218p1h3gxut3ku00u1k1da"));
7696
txBuilder.withValue(value);
7797
RawTransaction rawTx = txBuilder.build(cfx);
7898
// get account from accountManager, `account.send` will sign the tx and send it to blockchain
@@ -88,22 +108,7 @@ If you just want to transfer some CFX, there is a simpler method `account.transf
88108
Option opt = new Option();
89109
opt.withChainId(1);
90110
account.waitForNonceUpdated();
91-
String result = account.transfer(opt, "0x13d2bA4eD43542e7c54fbB6c5fCCb9f269C1f94C", value);
92-
```
93-
94-
95-
96-
## Conflux Address
97-
There are three types of address in Conflux:
98-
- User address: starts with `0x1`.
99-
- Contract address: starts with `0x8`.
100-
- Internal contract: starts with `0x0`.
101-
102-
Conflux Java SDK provides some utilities to validate or format address, please refer to `Address` and `AddressType` for more details.
103-
104-
The underlying library `Web3j` also provides API to convert address to a checksumed format.
105-
```java
106-
Keys.toChecksumAddress(String address)
111+
String result = account.transfer(opt, new Address("0x13d2bA4eD43542e7c54fbB6c5fCCb9f269C1f94C"), value);
107112
```
108113

109114
## Websocket and PubSub
@@ -136,16 +141,16 @@ To simple call a contract method you can use the ContractCall class
136141
package conflux.sdk.examples;
137142
import conflux.web3j.contract.ContractCall;
138143

139-
import org.web3j.abi.datatypes.Address;
144+
import conflux.web3j.types.Address;
140145
import conflux.web3j.contract.abi.DecodeUtil;
141146
import org.web3j.abi.datatypes.generated.Uint256;
142147

143148
public class App {
144149
public static void main(String[] args) throws Exception {
145-
ContractCall contract = new ContractCall(cfx, "0x824df34537b198d9955c01c4e5a2a68733707b4f");
150+
ContractCall contract = new ContractCall(cfx, new Address("0x824df34537b198d9955c01c4e5a2a68733707b4f", 1));
146151
// passing method name and parameter to `contract.call`
147152
// note: parameters should use web3j.abi.datatypes type
148-
String amount = contract.call("balanceOf", new Address("0x1386B4185A223EF49592233b69291bbe5a80C527")).sendAndGet();
153+
String amount = contract.call("balanceOf", new Address("0x1386B4185A223EF49592233b69291bbe5a80C527", 1).getABIAddress()).sendAndGet();
149154
BigInteger balance = DecodeUtil.decode(amount, Uint256.class);
150155
System.out.print("account balance: ");
151156
System.out.println(balance);
@@ -163,21 +168,22 @@ package conflux.sdk.examples;
163168
import conflux.web3j.Account;
164169
import conflux.web3j.Account.Option;
165170

166-
import org.web3j.abi.datatypes.Address;
171+
import conflux.web3j.types.Address;
167172
import org.web3j.abi.datatypes.generated.Uint256;
168173

169174
public class App {
170175
public static void main(String[] args) throws Exception {
171176
String privateKey = "0xxxxxx";
172-
String contractAddress = "0xxxxx";
173-
String recipient = "0xxxx";
177+
int netId = 1;
178+
Address contractAddress = new Address("0xxxxx", netId);
179+
Address recipient = new Address("0xxxx", netId);
174180
BigInteger amount = 100;
175181

176182
// create account, then call contract's method
177183
Account account = Account.create(cfx, privateKey);
178184
Option opt = new Option();
179185
// build transaction option info: nonce, gas, gasPrice and etc
180-
String txHash = account.call(option, contractAddress, "transfer", new Address(recipient), new Uint256(amount));
186+
String txHash = account.call(option, contractAddress, "transfer", recipient.getABIAddress(), new Uint256(amount));
181187
System.out.println("tx hash: " + txHash);
182188
}
183189
}

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ dependencies {
2626

2727
// Use JUnit test framework
2828
testImplementation 'junit:junit:4.12'
29-
29+
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
30+
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
31+
3032
compile 'org.web3j:core:4.6.3'
3133
}

docs/cfx-address.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CIP37 address
2+
===

src/main/java/conflux/web3j/Account.java

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.Arrays;
77
import java.util.Collections;
88

9+
import conflux.web3j.types.*;
910
import org.web3j.abi.FunctionEncoder;
1011
import org.web3j.abi.datatypes.Function;
1112
import org.web3j.abi.datatypes.Type;
@@ -17,48 +18,42 @@
1718

1819
import conflux.web3j.request.Call;
1920
import conflux.web3j.response.UsedGasAndCollateral;
20-
import conflux.web3j.types.AddressType;
21-
import conflux.web3j.types.RawTransaction;
22-
import conflux.web3j.types.SendTransactionError;
23-
import conflux.web3j.types.SendTransactionResult;
24-
import conflux.web3j.types.TransactionBuilder;
2521

2622
public class Account {
2723

2824
private Cfx cfx;
29-
private String address;
25+
private Address address;
3026
private BigInteger nonce;
3127

3228
private AccountManager am;
3329
private ECKeyPair ecKeyPair;
3430

35-
private Account(Cfx cfx, String address) {
31+
private Account(Cfx cfx, Address address) {
3632
this.cfx = cfx;
3733
this.address = address;
38-
this.nonce = cfx.getNonce(address).sendAndGet();
34+
this.nonce = cfx.getNonce(this.address).sendAndGet();
3935
}
4036

41-
public static Account unlock(Cfx cfx, AccountManager am, String address, String password) throws Exception {
37+
public static Account unlock(Cfx cfx, AccountManager am, Address address, String password) throws Exception {
4238
return unlock(cfx, am, address, password, Duration.ZERO);
4339
}
4440

45-
public static Account unlock(Cfx cfx, AccountManager am, String address, String password, Duration unlockTimeout) throws Exception {
41+
public static Account unlock(Cfx cfx, AccountManager am, Address address, String password, Duration unlockTimeout) throws Exception {
4642
if (!am.unlock(address, password, unlockTimeout)) {
4743
throw new Exception("account not found in keystore");
4844
}
4945

5046
Account account = new Account(cfx, address);
5147
account.am = am;
52-
5348
return account;
5449
}
5550

56-
public static Account create(Cfx cfx, String privateKey) {
51+
public static Account create(Cfx cfx, String privateKey) throws AddressException {
5752
Credentials credentials = Credentials.create(privateKey);
58-
59-
Account account = new Account(cfx, AddressType.User.normalize(credentials.getAddress()));
53+
String hexAddress = AddressType.User.normalize(credentials.getAddress());
54+
Address address = new Address(hexAddress, cfx.getIntNetworkId());
55+
Account account = new Account(cfx, address);
6056
account.ecKeyPair = credentials.getEcKeyPair();
61-
6257
return account;
6358
}
6459

@@ -67,9 +62,13 @@ public Cfx getCfx() {
6762
return cfx;
6863
}
6964

70-
public String getAddress() {
65+
public Address getAddress() {
7166
return address;
7267
}
68+
69+
public String getHexAddress() {
70+
return this.address.getHexAddress();
71+
}
7372

7473
public BigInteger getNonce() {
7574
return nonce;
@@ -81,7 +80,7 @@ public void setNonce(BigInteger nonce) {
8180

8281
public String sign(RawTransaction tx) throws Exception {
8382
return this.ecKeyPair == null
84-
? this.am.signTransaction(tx, this.address)
83+
? this.am.signTransaction(tx, this.getAddress())
8584
: tx.sign(this.ecKeyPair);
8685
}
8786

@@ -127,11 +126,11 @@ public SendTransactionResult send(RawTransaction tx) throws Exception {
127126
return this.send(signedTx);
128127
}
129128

130-
public String transfer(String to, BigInteger value) throws Exception {
129+
public String transfer(Address to, BigInteger value) throws Exception {
131130
return this.transfer(new Option(), to, value);
132131
}
133132

134-
public String transfer(Option option, String to, BigInteger value) throws Exception {
133+
public String transfer(Option option, Address to, BigInteger value) throws Exception {
135134
option.apply(this.cfx);
136135
RawTransaction tx = RawTransaction.transfer(this.nonce, to, value, option.epochHeight);
137136
option.updatePriceAndChainId(tx);
@@ -144,17 +143,17 @@ public String deploy(String bytecodes) throws Exception {
144143
}
145144

146145
public String deploy(Option option, String bytecodes) throws Exception {
147-
option.apply(this.cfx, this.address, "", bytecodes);
146+
option.apply(this.cfx, this.getAddress(), null, bytecodes);
148147
RawTransaction tx = RawTransaction.deploy(this.nonce, option.gasLimit, option.value, option.storageLimit, option.epochHeight, bytecodes);
149148
option.updatePriceAndChainId(tx);
150149
return this.mustSend(tx);
151150
}
152151

153-
public String call(String contract, String method, Type<?>... inputs) throws Exception {
152+
public String call(Address contract, String method, Type<?>... inputs) throws Exception {
154153
return this.call(new Option(), contract, method, inputs);
155154
}
156155

157-
public String call(Option option, String contract, String method, Type<?>... inputs) throws Exception {
156+
public String call(Option option, Address contract, String method, Type<?>... inputs) throws Exception {
158157
String data = "";
159158

160159
if (!Strings.isEmpty(method)) {
@@ -165,12 +164,12 @@ public String call(Option option, String contract, String method, Type<?>... inp
165164
return this.call(option, contract, data);
166165
}
167166

168-
public String call(String contract, String data) throws Exception {
167+
public String call(Address contract, String data) throws Exception {
169168
return this.call(new Option(), contract, data);
170169
}
171170

172-
public String call(Option option, String contract, String data) throws Exception {
173-
option.apply(this.cfx, this.address, contract, data);
171+
public String call(Option option, Address contract, String data) throws Exception {
172+
option.apply(this.cfx, this.getAddress(), contract, data);
174173
RawTransaction tx = RawTransaction.create(this.nonce, option.gasLimit, contract, option.value, option.storageLimit, option.epochHeight, data);
175174
option.updatePriceAndChainId(tx);
176175
return this.mustSend(tx);
@@ -260,7 +259,7 @@ private void apply(Cfx cfx) {
260259
}
261260
}
262261

263-
private void apply(Cfx cfx, String from, String to, String data) {
262+
private void apply(Cfx cfx, Address from, Address to, String data) {
264263
if (this.epochHeight == null) {
265264
this.epochHeight = cfx.getEpochNumber().sendAndGet();
266265
}
@@ -271,11 +270,11 @@ private void apply(Cfx cfx, String from, String to, String data) {
271270

272271
Call call = new Call();
273272

274-
if (!Strings.isEmpty(from)) {
273+
if (from != null) {
275274
call.setFrom(from);
276275
}
277276

278-
if (!Strings.isEmpty(to)) {
277+
if (to != null) {
279278
call.setTo(to);
280279
}
281280

0 commit comments

Comments
 (0)