Skip to content

Commit 46b1ca7

Browse files
committed
chore(wallet): create verify wallet and send capacity
1 parent dd00ef0 commit 46b1ca7

10 files changed

Lines changed: 266 additions & 132 deletions

File tree

console/src/main/java/org/nervos/ckb/example/AlwaysSuccessWalletClient.java

Lines changed: 0 additions & 16 deletions
This file was deleted.

console/src/main/java/org/nervos/ckb/example/VerifyWalletClient.java

Lines changed: 0 additions & 36 deletions
This file was deleted.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.nervos.ckb.example;
2+
3+
import com.google.gson.Gson;
4+
import org.nervos.ckb.methods.type.Transaction;
5+
import org.nervos.ckb.rpc.RpcRequest;
6+
import org.nervos.ckb.wallet.AlwaysSuccessWallet;
7+
import org.nervos.ckb.wallet.VerifyWallet;
8+
9+
import java.io.IOException;
10+
11+
/**
12+
* Created by duanyytop on 2019-01-31.
13+
* Copyright © 2018 Nervos Foundation. All rights reserved.
14+
*/
15+
public class WalletClient {
16+
17+
public static void main(String[] args) throws Exception {
18+
19+
AlwaysSuccessWallet minerWallet = new AlwaysSuccessWallet();
20+
System.out.println("Miner's always success wallet address: " + minerWallet.getAddress() + " and balance: " + minerWallet.getBalance());
21+
22+
VerifyWallet bobWallet = VerifyWallet.createWithPrivateKey("e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3");
23+
System.out.println("Bob's signed wallet address: " + bobWallet.getAddress() + " and balance: " + bobWallet.getBalance());
24+
25+
System.out.println("Miner send 1000 capacity to Bob...");
26+
String minerHash = minerWallet.sendCapacity(bobWallet.getAddress(), 1000);
27+
Transaction transaction = RpcRequest.getTransaction(minerHash);
28+
29+
while(transaction == null) {
30+
System.out.println("The transaction are packaging into blockchain");
31+
transaction = RpcRequest.getTransaction(minerHash);
32+
Thread.sleep(6000);
33+
}
34+
System.out.println("Miner's transaction: " + new Gson().toJson(transaction));
35+
System.out.println("Bob's signed wallet address: " + bobWallet.getAddress() + " and balance: " + bobWallet.getBalance());
36+
37+
VerifyWallet aliceWallet = VerifyWallet.createWithPrivateKey("76e853efa8245389e33f6fe49dcbd359eb56be2f6c3594e12521d2a806d32156");
38+
System.out.println("Alice's signed wallet address: " + aliceWallet.getAddress() + " and balance: " + aliceWallet.getBalance());
39+
40+
System.out.println("Bob send 100 capacity to Alice...");
41+
String bobHash = bobWallet.sendCapacity(aliceWallet.getAddress(), 100);
42+
Transaction bobTransaction = RpcRequest.getTransaction(bobHash);
43+
44+
while(bobTransaction == null) {
45+
System.out.println("The transaction are packaging into blockchain");
46+
Thread.sleep(6000);
47+
bobTransaction = RpcRequest.getTransaction(bobHash);
48+
}
49+
System.out.println("Bob's transaction: " + new Gson().toJson(bobTransaction));
50+
51+
System.out.println("Bob's signed wallet address: " + bobWallet.getAddress() + " and balance: " + bobWallet.getBalance());
52+
System.out.println("Alice's signed wallet address: " + aliceWallet.getAddress() + " and balance: " + aliceWallet.getBalance());
53+
54+
}
55+
56+
57+
58+
}

console/src/main/java/org/nervos/ckb/rpc/RpcRequest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import java.io.IOException;
1010
import java.math.BigInteger;
11+
import java.util.Arrays;
12+
import java.util.Collections;
1113
import java.util.List;
1214

1315
/**
@@ -81,9 +83,9 @@ public static String alwaysSuccessCellHash() throws IOException {
8183
return Hash.sha3(systemCells.get(0).data);
8284
}
8385

84-
public static OutPoint alwaysSuccessScriptOutPoint() throws IOException {
86+
public static List<OutPoint> alwaysSuccessScriptOutPoint() throws IOException {
8587
String hash = genesisBlock().commitTransactions.get(0).hash;
86-
return new OutPoint(hash, 0);
88+
return Arrays.asList(new OutPoint(hash, 0));
8789
}
8890

8991
}
Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,76 @@
11
package org.nervos.ckb.wallet;
22

3+
import org.nervos.ckb.exception.CapacityException;
4+
import org.nervos.ckb.methods.type.*;
5+
import org.nervos.ckb.rpc.RpcRequest;
6+
import org.nervos.ckb.utils.TransactionUtils;
7+
8+
import java.io.IOException;
9+
import java.util.ArrayList;
10+
import java.util.Collections;
11+
import java.util.List;
12+
313
/**
414
* Created by duanyytop on 2019-01-29.
515
* Copyright © 2018 Nervos Foundation. All rights reserved.
616
*/
7-
public class AlwaysSuccessWallet {
17+
public class AlwaysSuccessWallet extends BaseWallet {
18+
19+
public AlwaysSuccessWallet(){
20+
21+
}
22+
23+
@Override
24+
public String sendCapacity(String toAddress, long capacity) {
25+
Transaction tx = generateTx(toAddress, capacity);
26+
try {
27+
return RpcRequest.sendTransaction(TransactionUtils.formatTx(tx));
28+
} catch (IOException e) {
29+
e.printStackTrace();
30+
}
31+
return null;
32+
}
33+
34+
@Override
35+
protected Transaction generateTx(String toAddress, long capacity) {
36+
try {
37+
ValidInputs validInput = gatherInputs(getAddress(), capacity, Constant.MIN_CELL_CAPACITY);
38+
long inputCapacity = validInput.capacity;
39+
List<Output> outputs = new ArrayList<>();
40+
outputs.add(new Output(capacity, "", toAddress));
41+
if (inputCapacity > capacity) {
42+
outputs.add(new Output(inputCapacity - capacity, "", getAddress()));
43+
}
44+
return new Transaction(0, getDepsForOutPoint(), validInput.inputs, outputs);
45+
} catch (CapacityException e) {
46+
e.printStackTrace();
47+
}
48+
return null;
49+
}
50+
51+
@Override
52+
public String getAddress() {
53+
return getUnlockScript().getTypeHash();
54+
}
55+
56+
@Override
57+
protected Script getUnlockScript() {
58+
try {
59+
return new Script(0, RpcRequest.alwaysSuccessCellHash(), Collections.emptyList(), Collections.emptyList());
60+
} catch (IOException e) {
61+
e.printStackTrace();
62+
}
63+
return null;
64+
}
865

66+
@Override
67+
protected List<OutPoint> getDepsForOutPoint() {
68+
try {
69+
return RpcRequest.alwaysSuccessScriptOutPoint();
70+
} catch (IOException e) {
71+
e.printStackTrace();
72+
}
73+
return Collections.emptyList();
74+
}
975

1076
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package org.nervos.ckb.wallet;
2+
3+
import org.nervos.ckb.exception.CapacityException;
4+
import org.nervos.ckb.methods.type.*;
5+
import org.nervos.ckb.rpc.RpcRequest;
6+
7+
import java.io.IOException;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
/**
12+
* Created by duanyytop on 2019-02-01.
13+
* Copyright © 2018 Nervos Foundation. All rights reserved.
14+
*/
15+
public abstract class BaseWallet implements WalletAction {
16+
17+
@Override
18+
public long getBalance() {
19+
List<Cell> cells = getUnSpendCells(getAddress());
20+
long balance = 0;
21+
for (Cell cell: cells) {
22+
balance += cell.capacity;
23+
}
24+
return balance;
25+
}
26+
27+
protected abstract Transaction generateTx(String toAddress, long capacity);
28+
29+
ValidInputs gatherInputs(String address, long capacity, long minCapacity) throws CapacityException {
30+
if (capacity < minCapacity) {
31+
throw new CapacityException("capacity cannot be less than " + minCapacity);
32+
}
33+
long inputCapacities = 0;
34+
List<Input> inputs = new ArrayList<>();
35+
List<Cell> cells = getUnSpendCells(address);
36+
for (Cell cell: cells) {
37+
Input input = new Input(new Input.PreviousOutput(cell.outPoint.hash, cell.outPoint.index), getUnlockScript());
38+
inputs.add(input);
39+
inputCapacities += cell.capacity;
40+
if (inputCapacities >= capacity && (inputCapacities - capacity) >= minCapacity) {
41+
break;
42+
}
43+
}
44+
if (inputCapacities < capacity) {
45+
throw new CapacityException("Not enough capacity!");
46+
}
47+
return new ValidInputs(inputs, inputCapacities);
48+
}
49+
50+
class ValidInputs {
51+
List<Input> inputs;
52+
long capacity;
53+
54+
ValidInputs(List<Input> inputs, long capacity) {
55+
this.inputs = inputs;
56+
this.capacity = capacity;
57+
}
58+
}
59+
60+
protected abstract Script getUnlockScript();
61+
62+
63+
List<Cell> getUnSpendCells(String address) {
64+
List<Cell> results = new ArrayList<>();
65+
try {
66+
long toBlockNumber = RpcRequest.getTipBlockNumber().longValue();
67+
long fromBlockNumber = 1;
68+
while (fromBlockNumber <= toBlockNumber) {
69+
long currentToBlockNumber = Math.min(fromBlockNumber + 100, toBlockNumber);
70+
List<Cell> cells = RpcRequest.getCellsByTypeHash(address, fromBlockNumber, currentToBlockNumber);
71+
if (cells != null && cells.size() > 0) {
72+
results.addAll(cells);
73+
}
74+
fromBlockNumber = currentToBlockNumber + 1;
75+
}
76+
} catch (IOException e) {
77+
e.printStackTrace();
78+
}
79+
return results;
80+
}
81+
82+
protected abstract List<OutPoint> getDepsForOutPoint();
83+
84+
}

0 commit comments

Comments
 (0)