diff --git a/pom.xml b/pom.xml
index 217454c..c99c57c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -54,5 +54,10 @@
+
+
+ src/main/java/NEO/data
+
+
diff --git a/src/main/java/Demo/GlobalAssetDemo.java b/src/main/java/Demo/GlobalAssetDemo.java
new file mode 100644
index 0000000..101003f
--- /dev/null
+++ b/src/main/java/Demo/GlobalAssetDemo.java
@@ -0,0 +1,123 @@
+package Demo;
+
+import NEO.Core.Blockchain;
+import NEO.Core.SignatureContext;
+import NEO.Core.Transaction;
+import NEO.Fixed8;
+import NEO.Helper;
+import NEO.IO.Json.JArray;
+import NEO.IO.Json.JNumber;
+import NEO.IO.Json.JObject;
+import NEO.IO.Json.JString;
+import NEO.Settings;
+import NEO.UInt160;
+import NEO.Wallets.Account;
+import NEO.Wallets.Contract;
+import NEO.Wallets.Wallet;
+import NEO.sdk.SmartContractTx;
+import NEO.sdk.wallet.AccountManager;
+
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class GlobalAssetDemo {
+
+ // exported WIF from wallet
+ public static final String WALLET_WIF1 = "KxQVgnGyoHNA9h4k2as9TDPczsSwzUbH2Y8Bfku65AJiomB3wkg6";
+ public static final String WALLET_WIF2 = "L4vr3XmcqGNJzwVfABiVtZbJajhNUWv6ny9Ggv7HYbhBy8rxMReU";
+ public Contract contract;
+
+ public static void main(String[] args) throws Exception {
+
+ // import setting
+ Settings.getSettings(Settings.CONFIG_PRIVNET);
+
+ // new AccountManager
+ AccountManager wm = getAccountManager();
+
+ // start block sync
+ wm.startSyncBlock();
+
+ // check height
+ while (!wm.hasFinishedSyncBlock()) {
+ Thread.sleep(1000 * 1);
+ }
+
+ // import two account from WIF
+ String address1 = wm.createAccountsFromPrivateKey(Helper.toHexString(Wallet.getPrivateKeyFromWIF(WALLET_WIF1)));
+ Account account1 = wm.getAccount(address1);
+ Contract contract1 = Contract.createSignatureContract(account1.publicKey);
+ System.out.println("contract1 address:" + address1);
+
+ String address2 = wm.createAccountsFromPrivateKey(Helper.toHexString(Wallet.getPrivateKeyFromWIF(WALLET_WIF2)));
+ Account account2 = wm.getAccount(address2);
+ Contract contract2 = Contract.createSignatureContract(account2.publicKey);
+ System.out.println("contract2 address:" + address2);
+
+ // check balance
+ System.out.println(wm.getAccountAsset(address1));
+ System.out.println(wm.getAccountAsset(address2));
+
+ // make transaction
+ Fixed8 fee = new Fixed8();
+ Transaction tx = SmartContractTx.makeContractTransaction(address2, Blockchain.GoverningToken, Fixed8.ONE, fee);
+ System.out.println(tx.hash().toString());
+ tx = wm.makeTransaction(tx, fee, Wallet.toScriptHash(address1));
+
+ // sign tx
+ SignatureContext context = new SignatureContext(tx, new UInt160[]{Wallet.toScriptHash(contract1.address())});
+ byte[] signature = context.signable.sign(account1);
+ if (!context.add(contract1, account1.publicKey, signature))
+ throw new Exception();
+ if (context.isCompleted()) {
+ tx.scripts = context.getScripts();
+ System.out.println("scripts:" + tx.scripts[0].json());
+ }
+
+ // checkout transaction
+ String txHex = Helper.toHexString(tx.toArray());
+ System.out.println("tx:" + tx.json());
+
+ // make request
+ JObject[] params = new JObject[]{ new JString(Helper.toHexString(tx.toArray())) };
+
+ JObject request = new JObject();
+ request.set("jsonrpc", new JString("2.0"));
+ request.set("method", new JString("sendrawtransaction"));
+ request.set("params", new JArray(params));
+ request.set("id", new JNumber(1));
+
+ // send request
+ HttpURLConnection connection = (HttpURLConnection) new URL(Settings.RPC_LIST.get(0)).openConnection();
+ connection.setRequestMethod("POST");
+ connection.setDoOutput(true);
+
+ // wait result
+ try (OutputStreamWriter w = new OutputStreamWriter(connection.getOutputStream())) {
+ w.write(request.toString());
+ }
+ try (InputStreamReader r = new InputStreamReader(connection.getInputStream())) {
+ System.out.println(JObject.parse(r));
+ }
+ }
+
+ public static AccountManager getAccountManager() throws MalformedURLException {
+ // v1.2
+ String neoUrl = Settings.RPC_LIST.get(0);
+ String neoToken = "";
+ String path = "./1.db3";
+ AccountManager wm = AccountManager.getWallet(path, neoUrl, neoToken);
+ print(String.format("[param=%s,%s]", neoUrl, path));
+ print(String.format("start to test....hh:%s", wm.getBlockHeight()));
+ return wm;
+ }
+
+ private static void print(String ss) {
+ System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()) + " " + ss);
+ }
+}
diff --git a/src/main/java/Demo/RawTxDemo.java b/src/main/java/Demo/RawTxDemo.java
new file mode 100644
index 0000000..031130e
--- /dev/null
+++ b/src/main/java/Demo/RawTxDemo.java
@@ -0,0 +1,136 @@
+package Demo;
+
+import NEO.*;
+import NEO.Core.*;
+import NEO.Core.Scripts.Program;
+import NEO.IO.Json.JArray;
+import NEO.IO.Json.JNumber;
+import NEO.IO.Json.JObject;
+import NEO.IO.Json.JString;
+import NEO.Wallets.Account;
+import NEO.Wallets.Contract;
+import NEO.Wallets.Wallet;
+import NEO.sdk.wallet.AccountManager;
+
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class RawTxDemo {
+
+ // exported WIF from wallet
+ public static final String WALLET_WIF2 = "KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr";
+ public static final String WALLET_WIF1 = "L4vr3XmcqGNJzwVfABiVtZbJajhNUWv6ny9Ggv7HYbhBy8rxMReU";
+ public Contract contract;
+
+ public static void main(String[] args) throws Exception {
+
+ // import setting
+ Settings.getSettings(Settings.CONFIG_PRIVNET);
+
+ // new AccountManager
+ String neoUrl = Settings.RPC_LIST.get(0);
+ String neoToken = "";
+ String path = "./1.db3";
+ AccountManager wm = AccountManager.getWallet(path, neoUrl, neoToken);
+ System.out.println("[param=" + neoUrl + "," + path + "]");
+ System.out.println("start to test....hh:" + wm.getBlockHeight());
+
+ // start block sync
+ wm.startSyncBlock();
+
+ // check height
+ while (!wm.hasFinishedSyncBlock()) {
+ Thread.sleep(1000 * 1);
+ }
+
+ // import two account from WIF
+ String address1 = wm.createAccountsFromPrivateKey(Helper.toHexString(Wallet.getPrivateKeyFromWIF(WALLET_WIF1)));
+ Account account1 = wm.getAccount(address1);
+ Contract contract1 = Contract.createSignatureContract(account1.publicKey);
+ System.out.println("contract1 address:" + address1);
+
+ String address2 = wm.createAccountsFromPrivateKey(Helper.toHexString(Wallet.getPrivateKeyFromWIF(WALLET_WIF2)));
+ Account account2 = wm.getAccount(address2);
+ Contract contract2 = Contract.createSignatureContract(account2.publicKey);
+ System.out.println("contract2 address:" + address2);
+
+ // check balance
+ System.out.println(wm.getAccountAsset(address1));
+ System.out.println(wm.getAccountAsset(address2));
+
+ // make transaction
+ ContractTransaction tx = new ContractTransaction();
+
+ // neo input
+ TransactionInput inputN = new TransactionInput();
+ inputN.prevIndex = 0;
+ inputN.prevHash = UInt256.parse("072497994952d898e4f302d7b7022cbfd368d2b2ede4f51a0a3e41af22278e87");
+
+ // gas input
+ TransactionInput inputG = new TransactionInput();
+ inputG.prevIndex = 0;
+ inputG.prevHash = UInt256.parse("ede0cfea66811f194c1d82b8d8377f941c8cc8bae3adfed0a77c5eb7bb5e96a9");
+
+ // neo output
+ TransactionOutput outputN = new TransactionOutput();
+ outputN.assetId = Blockchain.GoverningToken;
+ outputN.value = Fixed8.ONE;
+ outputN.scriptHash = Wallet.toScriptHash(address2);
+
+ // gas output
+ TransactionOutput outputG = new TransactionOutput();
+ outputG.assetId = Blockchain.UtilityToken;
+ outputG.value = new Fixed8((long)(0.999 * (long)Math.pow(10, 8)));
+ outputG.scriptHash = Wallet.toScriptHash(address1);
+
+ tx.version = 0;
+ tx.attributes = new TransactionAttribute[0];
+ tx.inputs = new TransactionInput[2];
+ tx.inputs[0] = inputN;
+ tx.inputs[1] = inputG;
+ tx.outputs = new TransactionOutput[2];
+ tx.outputs[0] = outputN;
+ tx.outputs[1] = outputG;
+ tx.scripts = new Program[0];
+
+ System.out.println(tx.hash().toString());
+
+ // sign tx
+ SignatureContext context = new SignatureContext(tx, new UInt160[]{Wallet.toScriptHash(contract1.address())});
+ byte[] signature = context.signable.sign(account1);
+ if (!context.add(contract1, account1.publicKey, signature))
+ throw new Exception();
+ if (context.isCompleted()) {
+ tx.scripts = context.getScripts();
+ System.out.println("scripts:" + tx.scripts[0].json());
+ }
+
+ // checkout transaction
+ String txHex = Helper.toHexString(tx.toArray());
+ System.out.println("tx:" + tx.json());
+
+ // make request
+ JObject[] params = new JObject[]{ new JString(Helper.toHexString(tx.toArray())) };
+
+ JObject request = new JObject();
+ request.set("jsonrpc", new JString("2.0"));
+ request.set("method", new JString("sendrawtransaction"));
+ request.set("params", new JArray(params));
+ request.set("id", new JNumber(1));
+
+ // send request
+ HttpURLConnection connection = (HttpURLConnection) new URL(Settings.RPC_LIST.get(0)).openConnection();
+ connection.setRequestMethod("POST");
+ connection.setDoOutput(true);
+
+ // wait result
+ try (OutputStreamWriter w = new OutputStreamWriter(connection.getOutputStream())) {
+ w.write(request.toString());
+ }
+ try (InputStreamReader r = new InputStreamReader(connection.getInputStream())) {
+ System.out.println(JObject.parse(r));
+ }
+ }
+}
diff --git a/src/main/java/NEO/Core/Blockchain.java b/src/main/java/NEO/Core/Blockchain.java
index b50d388..4a55a11 100644
--- a/src/main/java/NEO/Core/Blockchain.java
+++ b/src/main/java/NEO/Core/Blockchain.java
@@ -100,6 +100,10 @@ public abstract class Blockchain implements AutoCloseable {
@Override
public abstract void close();
+ public static final UInt256 GoverningToken = UInt256.parse("c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b");
+
+ public static final UInt256 UtilityToken = UInt256.parse("602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7");
+
/**
* 判断区块链中是否包含指定的资产
* 资产编号
diff --git a/src/main/java/NEO/Core/ClaimTransaction.java b/src/main/java/NEO/Core/ClaimTransaction.java
new file mode 100644
index 0000000..9e5bbfd
--- /dev/null
+++ b/src/main/java/NEO/Core/ClaimTransaction.java
@@ -0,0 +1,58 @@
+package NEO.Core;
+
+import NEO.IO.BinaryReader;
+import NEO.IO.BinaryWriter;
+import NEO.UInt160;
+import NEO.UInt256;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class ClaimTransaction extends Transaction{
+
+ public TransactionInput[] claims;
+
+ public ClaimTransaction() {
+ super(TransactionType.ClaimTransaction);
+ }
+
+ @Override
+ protected void deserializeExclusiveData(BinaryReader reader) throws IOException {
+ try {
+ claims = reader.readSerializableArray(TransactionInput.class);
+ }
+ catch (Exception e) {
+ throw new IOException();
+ }
+ }
+
+ @Override
+ public UInt160[] getScriptHashesForVerifying() {
+ HashSet hashs = new HashSet(Arrays.asList(super.getScriptHashesForVerifying()));
+ for (Map.Entry> group : Arrays.stream(claims).collect(Collectors.groupingBy(p -> p.prevHash)).entrySet()) {
+ try {
+ Transaction tx = Blockchain.current().getTransaction(group.getKey());
+ if (tx == null)
+ throw new IllegalStateException();
+ for (TransactionInput claim : group.getValue()) {
+ if (tx.outputs.length <= claim.prevIndex)
+ throw new IllegalStateException();
+ hashs.add(tx.outputs[claim.prevIndex].scriptHash);
+ }
+ }
+ catch (Exception e) {
+ throw new IllegalStateException();
+ }
+ }
+ return hashs.stream().sorted().toArray(UInt160[]::new);
+ }
+
+ @Override
+ protected void serializeExclusiveData(BinaryWriter writer) throws IOException {
+ writer.writeSerializableArray(claims);
+ }
+}
diff --git a/src/main/java/NEO/Core/MinerTransaction.java b/src/main/java/NEO/Core/MinerTransaction.java
index ca80f50..0068835 100644
--- a/src/main/java/NEO/Core/MinerTransaction.java
+++ b/src/main/java/NEO/Core/MinerTransaction.java
@@ -14,9 +14,7 @@ public MinerTransaction() {
@Override
protected void deserializeExclusiveData(BinaryReader reader) throws IOException {
- if(version == 3) {
- nonce = reader.readLong();
- }
+ nonce = reader.readInt();
}
@Override
@@ -25,4 +23,15 @@ protected void serializeExclusiveData(BinaryWriter writer) throws IOException {
writer.writeLong(nonce);
}
}
+
+ @Override
+ protected void onDeserialized() throws IOException{
+ if (inputs.length != 0)
+ throw new IOException();
+ for (TransactionOutput output : outputs) {
+ //if (output.assetId != Blockchain.utilityToken().hash())
+ if (output.assetId != Blockchain.UtilityToken)
+ throw new IOException();
+ }
+ }
}
diff --git a/src/main/java/NEO/Core/TransactionAttribute.java b/src/main/java/NEO/Core/TransactionAttribute.java
index 92be940..7cb232e 100644
--- a/src/main/java/NEO/Core/TransactionAttribute.java
+++ b/src/main/java/NEO/Core/TransactionAttribute.java
@@ -31,15 +31,17 @@ public void serialize(BinaryWriter writer) throws IOException {
// usage
writer.writeByte(usage.value());
// data
- if (usage == TransactionAttributeUsage.Script){
+ if (usage == TransactionAttributeUsage.DescriptionUrl){
+ writer.writeByte((byte)data.length);
+ }
+ else if (usage == TransactionAttributeUsage.Description || usage.value() >= TransactionAttributeUsage.Remark.value()) {
+ writer.writeVarInt(data.length);
+ }
+ if (usage == TransactionAttributeUsage.ECDH02 || usage == TransactionAttributeUsage.ECDH03) {
+ writer.write(data, 1, 32);
+ }
+ else
writer.write(data);
- }else if( usage == TransactionAttributeUsage.DescriptionUrl
- || usage == TransactionAttributeUsage.Description
- || usage == TransactionAttributeUsage.Nonce) {
- writer.writeVarBytes(data);
- } else {
- throw new IOException();
- }
}
@Override
@@ -47,15 +49,23 @@ public void deserialize(BinaryReader reader) throws IOException {
// usage
usage = TransactionAttributeUsage.valueOf(reader.readByte());
// data
- if (usage == TransactionAttributeUsage.Script){
+ if (usage == TransactionAttributeUsage.ContractHash || usage == TransactionAttributeUsage.Vote || (usage.value() >= TransactionAttributeUsage.Hash1.value() && usage.value() <= TransactionAttributeUsage.Hash15.value()))
+ data = reader.readBytes(32);
+ else if (usage == TransactionAttributeUsage.ECDH02 || usage == TransactionAttributeUsage.ECDH03) {
+ byte[] part1 = data.clone();
+ byte[] part2 = reader.readBytes(32);
+ data = new byte[part1.length + part2.length];
+ System.arraycopy(part1, 0, data, 0, part1.length);
+ System.arraycopy(part2, 0, data, part1.length, part2.length);
+ }
+ else if (usage == TransactionAttributeUsage.Script)
data = reader.readBytes(20);
- }else if(usage == TransactionAttributeUsage.DescriptionUrl
- || usage == TransactionAttributeUsage.Description
- || usage == TransactionAttributeUsage.Nonce) {
- data = reader.readVarBytes(255);
- } else {
- throw new IOException();
- }
+ else if (usage == TransactionAttributeUsage.DescriptionUrl)
+ data = reader.readBytes(reader.readByte());
+ else if (usage == TransactionAttributeUsage.Description || usage.value() >= TransactionAttributeUsage.Remark.value())
+ data = reader.readVarBytes(65535);
+ else
+ throw new IOException();
}
public JObject json() {
diff --git a/src/main/java/NEO/Core/TransactionAttributeUsage.java b/src/main/java/NEO/Core/TransactionAttributeUsage.java
index 67ae502..7963e77 100644
--- a/src/main/java/NEO/Core/TransactionAttributeUsage.java
+++ b/src/main/java/NEO/Core/TransactionAttributeUsage.java
@@ -5,15 +5,66 @@
*/
public enum TransactionAttributeUsage {
- Nonce(0x00),
+ /**
+ * 外部合同散列值
+ */
+ ContractHash(0x00),
+
+ /**
+ * 用于ECDH密钥交换的公钥,该公钥的第一个字节为0x02
+ */
+ ECDH02(0x02),
+ /**
+ * 用于ECDH密钥交换的公钥,该公钥的第一个字节为0x03
+ */
+ ECDH03(0x03),
+
/**
* 用于对交易进行额外的验证
*/
Script(0x20),
+ Vote(0x30),
+
DescriptionUrl(0x81),
Description(0x90),
+ Hash1(0xa1),
+ Hash2(0xa2),
+ Hash3(0xa3),
+ Hash4(0xa4),
+ Hash5(0xa5),
+ Hash6(0xa6),
+ Hash7(0xa7),
+ Hash8(0xa8),
+ Hash9(0xa9),
+ Hash10(0xaa),
+ Hash11(0xab),
+ Hash12(0xac),
+ Hash13(0xad),
+ Hash14(0xae),
+ Hash15(0xaf),
+
+ /**
+ * 备注
+ */
+ Remark(0xf0),
+ Remark1(0xf1),
+ Remark2(0xf2),
+ Remark3(0xf3),
+ Remark4(0xf4),
+ Remark5(0xf5),
+ Remark6(0xf6),
+ Remark7(0xf7),
+ Remark8(0xf8),
+ Remark9(0xf9),
+ Remark10(0xfa),
+ Remark11(0xfb),
+ Remark12(0xfc),
+ Remark13(0xfd),
+ Remark14(0xfe),
+ Remark15(0xff),
+
;
private byte value;
diff --git a/src/main/java/NEO/Settings.java b/src/main/java/NEO/Settings.java
new file mode 100644
index 0000000..8612d1e
--- /dev/null
+++ b/src/main/java/NEO/Settings.java
@@ -0,0 +1,84 @@
+package NEO;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+public class Settings {
+
+ public static final String CONFIG_MAINNET = "protocol.mainnet.json";
+ public static final String CONFIG_TESTNET = "protocol.testnet.json";
+ public static final String CONFIG_PRIVNET = "protocol.privnet.json";
+
+
+ public static JSONObject PROTOCOL_CONFIGURATION;
+
+ public static long MAGIC;
+ public static long ADDRESS_VERSION;
+ public static List STANDBY_VALIDATORS;
+ public static List SEED_LIST;
+ public static List RPC_LIST;
+
+ public static JSONObject ALL_FEES;
+ public static long ENROLLMENT_TX_FEE;
+ public static long ISSUE_TX_FEE;
+ public static long PUBLISH_TX_FEE;
+ public static long REGISTER_TX_FEE;
+
+
+ public static JSONObject APPLICATION_CONFIGURATION;
+
+ public static String DATA_DIRECTORY_PATH;
+ public static String NOTIFICATION_DATA_PATH;
+ public static long RPC_PORT;
+ public static long NODE_PORT;
+ public static long WS_PORT;
+ public static List URI_PREFIX;
+ public static String SSL_CERT;
+ public static String SSL_CERT_PASSWORD;
+ public static String BOOTSTRAP_FILE;
+ public static String NOTIFICATION_BOOTSTRAP_FILE;
+ public static long DEBUG_STORAGE;
+
+ private Settings(){
+ }
+
+ public static void getSettings() throws IOException{
+ getSettings(CONFIG_TESTNET);
+ }
+
+ public static void getSettings(String config_file) throws IOException{
+
+ // Need a better path solution
+ String path = Settings.class.getClassLoader().getResource(config_file).getPath();
+ InputStream is = new FileInputStream(path);
+
+ byte[] bys = new byte[is.available()];
+ is.read(bys);
+ is.close();
+ JSONObject json = JSONObject.parseObject(new String(bys));
+
+ PROTOCOL_CONFIGURATION = json.getJSONObject("ProtocolConfiguration");
+
+ MAGIC = PROTOCOL_CONFIGURATION.getLong("Magic");
+ ADDRESS_VERSION = PROTOCOL_CONFIGURATION.getLong("AddressVersion");
+ STANDBY_VALIDATORS = JSON.parseArray(PROTOCOL_CONFIGURATION.getJSONArray("StandbyValidators").toString(), String.class);
+ SEED_LIST = JSON.parseArray(PROTOCOL_CONFIGURATION.getJSONArray("SeedList").toString(), String.class);
+ RPC_LIST = JSON.parseArray(PROTOCOL_CONFIGURATION.getJSONArray("RPCList").toString(), String.class);
+
+ ALL_FEES = PROTOCOL_CONFIGURATION.getJSONObject("SystemFee");
+
+ ENROLLMENT_TX_FEE = ALL_FEES.getLong("EnrollmentTransaction");
+ ISSUE_TX_FEE = ALL_FEES.getLong("IssueTransaction");
+ PUBLISH_TX_FEE = ALL_FEES.getLong("PublishTransaction");
+ REGISTER_TX_FEE = ALL_FEES.getLong("RegisterTransaction");
+
+
+ APPLICATION_CONFIGURATION = json.getJSONObject("ApplicationConfiguration");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/NEO/data/protocol.json b/src/main/java/NEO/data/protocol.json
new file mode 100644
index 0000000..75630cb
--- /dev/null
+++ b/src/main/java/NEO/data/protocol.json
@@ -0,0 +1,30 @@
+{
+ "ProtocolConfiguration": {
+ "Magic": 56753,
+ "AddressVersion": 23,
+ "StandbyValidators": [
+ "02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2",
+ "02103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e",
+ "03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699",
+ "02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62"
+ ],
+ "SeedList": [
+ "127.0.0.1:20333",
+ "127.0.0.1:20334",
+ "127.0.0.1:20335",
+ "127.0.0.1:20336"
+ ],
+ "RPCList":[
+ "http://127.0.0.1:30333"
+ ],
+ "SystemFee": {
+ "EnrollmentTransaction": 1000,
+ "IssueTransaction": 500,
+ "PublishTransaction": 500,
+ "RegisterTransaction": 10000
+ }
+ },
+
+ "ApplicationConfiguration": {
+ }
+}
diff --git a/src/main/java/NEO/data/protocol.mainnet.json b/src/main/java/NEO/data/protocol.mainnet.json
new file mode 100644
index 0000000..dbe1609
--- /dev/null
+++ b/src/main/java/NEO/data/protocol.mainnet.json
@@ -0,0 +1,40 @@
+{
+ "ProtocolConfiguration": {
+ "Magic": 7630401,
+ "AddressVersion": 23,
+ "StandbyValidators": [
+ "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c",
+ "02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093",
+ "03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a",
+ "02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554",
+ "024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d",
+ "02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e",
+ "02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70"
+ ],
+ "SeedList": [
+ "13.58.252.110:10333",
+ "18.216.146.68:10333",
+ "18.217.91.255:10333",
+ "18.218.62.119:10333",
+ "18.196.141.225:10333",
+ "seed2.neo.org:10333",
+ "seed3.neo.org:10333",
+ "seed1.redpulse.com:10333"
+ ],
+ "RPCList":[
+ "http://18.217.24.130:8080",
+ "http://18.220.214.143:8080",
+ "http://13.58.198.112:8080",
+ "http://13.59.14.206:8080",
+ "http://18.216.9.7:8080"
+ ],
+ "SystemFee": {
+ "EnrollmentTransaction": 1000,
+ "IssueTransaction": 500,
+ "PublishTransaction": 500,
+ "RegisterTransaction": 10000
+ }
+ },
+ "ApplicationConfiguration": {
+ }
+}
diff --git a/src/main/java/NEO/data/protocol.privnet.json b/src/main/java/NEO/data/protocol.privnet.json
new file mode 100644
index 0000000..f0fafec
--- /dev/null
+++ b/src/main/java/NEO/data/protocol.privnet.json
@@ -0,0 +1,30 @@
+{
+ "ProtocolConfiguration": {
+ "Magic": 56753,
+ "AddressVersion": 23,
+ "StandbyValidators": [
+ "02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2",
+ "02103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e",
+ "03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699",
+ "02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62"
+ ],
+ "SeedList": [
+ "127.0.0.1:20333",
+ "127.0.0.1:20334",
+ "127.0.0.1:20335",
+ "127.0.0.1:20336"
+ ],
+ "RPCList":[
+ "http://127.0.0.1:30333"
+ ],
+ "SystemFee": {
+ "EnrollmentTransaction": 1000,
+ "IssueTransaction": 500,
+ "PublishTransaction": 500,
+ "RegisterTransaction": 10000
+ }
+ },
+
+ "ApplicationConfiguration": {
+ }
+}
diff --git a/src/main/java/NEO/data/protocol.testnet.json b/src/main/java/NEO/data/protocol.testnet.json
new file mode 100644
index 0000000..ea3380f
--- /dev/null
+++ b/src/main/java/NEO/data/protocol.testnet.json
@@ -0,0 +1,37 @@
+{
+ "ProtocolConfiguration": {
+ "AddressVersion": 23,
+ "Magic": 1953787457,
+ "SeedList": [
+ "18.218.97.227:20333",
+ "18.219.30.120:20333",
+ "18.219.13.91:20333",
+ "13.59.116.121:20333",
+ "18.218.255.178:20333"
+ ],
+ "RPCList":[
+ "http://18.221.221.195:8880",
+ "http://18.221.139.152:8880",
+ "http://52.15.48.60:8880",
+ "http://18.221.0.152:8880",
+ "http://52.14.184.44:8880"
+ ],
+ "StandbyValidators": [
+ "0327da12b5c40200e9f65569476bbff2218da4f32548ff43b6387ec1416a231ee8",
+ "026ce35b29147ad09e4afe4ec4a7319095f08198fa8babbe3c56e970b143528d22",
+ "0209e7fd41dfb5c2f8dc72eb30358ac100ea8c72da18847befe06eade68cebfcb9",
+ "039dafd8571a641058ccc832c5e2111ea39b09c0bde36050914384f7a48bce9bf9",
+ "038dddc06ce687677a53d54f096d2591ba2302068cf123c1f2d75c2dddc5425579",
+ "02d02b1873a0863cd042cc717da31cea0d7cf9db32b74d4c72c01b0011503e2e22",
+ "034ff5ceeac41acf22cd5ed2da17a6df4dd8358fcb2bfb1a43208ad0feaab2746b"
+ ],
+ "SystemFee": {
+ "EnrollmentTransaction": 10,
+ "IssueTransaction": 5,
+ "PublishTransaction": 5,
+ "RegisterTransaction": 100
+ }
+ },
+ "ApplicationConfiguration": {
+ }
+}
diff --git a/src/main/java/NEO/sdk/SmartContractTx.java b/src/main/java/NEO/sdk/SmartContractTx.java
index 70355d1..e6fb8f3 100644
--- a/src/main/java/NEO/sdk/SmartContractTx.java
+++ b/src/main/java/NEO/sdk/SmartContractTx.java
@@ -6,13 +6,16 @@
import NEO.Core.Scripts.ScriptBuilder;
import NEO.Fixed8;
import NEO.Helper;
+import NEO.UInt256;
import NEO.Wallets.Contract;
+import NEO.Wallets.Wallet;
import NEO.sdk.abi.AbiFunction;
import NEO.sdk.abi.Parameter;
import com.alibaba.fastjson.JSON;
import org.bouncycastle.math.ec.ECPoint;
import java.lang.reflect.Array;
+import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
@@ -156,4 +159,34 @@ public static InvocationTransaction makeInvocationTransaction(byte[] paramsHexSt
tx.gas = new Fixed8(0);
return tx;
}
+
+ public static ContractTransaction makeContractTransaction(String toAddress, UInt256 assetId, Fixed8 amount, Fixed8 fee) {
+ ContractTransaction tx = new ContractTransaction();
+
+ TransactionOutput output = new TransactionOutput();
+ output.assetId = assetId;
+ output.value = amount;
+ output.scriptHash = Wallet.toScriptHash(toAddress);
+
+ tx.version = 0;
+ tx.attributes = new TransactionAttribute[0];
+ tx.inputs = new TransactionInput[0];
+ tx.outputs = new TransactionOutput[1];
+ tx.outputs[0] = output;
+ tx.scripts = new Program[0];
+
+ Fixed8 gasFee = null;
+ Fixed8 netFee = null;
+ if (tx.systemFee().compareTo(Fixed8.ZERO) <= 0) {
+ gasFee = Fixed8.ZERO;
+ netFee = Fixed8.fromDecimal(new BigDecimal("0.0001"));
+ }
+ else {
+ gasFee = tx.systemFee();
+ netFee = Fixed8.ZERO;
+ }
+
+ //fee.assign(netFee);
+ return tx;
+ }
}
diff --git a/src/main/java/NEO/sdk/wallet/AccountManager.java b/src/main/java/NEO/sdk/wallet/AccountManager.java
index 478fb2c..415de28 100644
--- a/src/main/java/NEO/sdk/wallet/AccountManager.java
+++ b/src/main/java/NEO/sdk/wallet/AccountManager.java
@@ -10,6 +10,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import NEO.Wallets.*;
import com.alibaba.fastjson.JSON;
import NEO.Fixed8;
@@ -37,10 +38,6 @@
import NEO.Implementations.Wallets.SQLite.UserWallet;
import NEO.Network.Rest.RestException;
import NEO.Network.Rest.RestNode;
-import NEO.Wallets.Account;
-import NEO.Wallets.Coin;
-import NEO.Wallets.Contract;
-import NEO.Wallets.Wallet;
import NEO.sdk.helper.OnChainSDKHelper;
import NEO.sdk.info.account.AccountAsset;
import NEO.sdk.info.account.AccountInfo;
@@ -235,7 +232,16 @@ public void setAuthType(String authType) {
public void setAccessToken(String accessToken) {
this.restNode.setAccessToken(accessToken);
}
-
+
+ @Deprecated
+ public Transaction makeTransaction(Transaction tx, Fixed8 fee) throws CoinException {
+ return this.uw.makeTransaction(tx, fee);
+ }
+
+ @Deprecated
+ public Transaction makeTransaction(Transaction tx, Fixed8 fee, UInt160 from) throws CoinException {
+ return this.uw.makeTransaction(tx, fee, from);
+ }
/**
* 注册资产
* @throws Exception