Skip to content

Commit

Permalink
Merge pull request #29 from nguyenphuminh/big-rewrite
Browse files Browse the repository at this point in the history
Big rewrite
  • Loading branch information
nguyenphuminh authored Jun 29, 2022
2 parents 60aa324 + b6390dd commit c5293a3
Show file tree
Hide file tree
Showing 25 changed files with 1,553 additions and 1,335 deletions.
65 changes: 42 additions & 23 deletions CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,40 @@ Before we dig in, we need to know that a contract's storage is a key-value objec

Arguments can be represented as `%0`, `%1`, `%2`,..., `%n`.

### Utils
### Block data

* Print out a value: `log value`.
* Store contract's balance into a variable: `balance var_name`.
* Store block's timestamp into a variable: `timestamp var_name`.
* Store sender's address into a variable: `address var_name`.
* Store block's number into a variable: `blocknumber var_name`.
* Store block's hash into a variable: `blockhash var_name`.
* Store block's difficulty into a variable: `difficulty var_name`.

### Transaction data

* Store transaction's amount into a variable: `txvalue var_name`.
* Store transaction's sender address into a variable: `txsender var_name`.
* Store transaction's gas into a variable: `txgas var_name`.
* Store transaction's contract execution gas into a variable: `txexecgas var_name`.

### Contract data

* Store contract's address into a variable: `address var_name`.
* Store contract's balance into a variable: `selfbalance var_name`.

### Chain interactions

* Store address's balance into a variable: `balance var_name, address`.
* Send Jem to an address: `send address, amount`.

### Others

* Print out a value: `log value`.
* Generate SHA256 hash of a value and store into a variable: `sha256 var_name, value`.
* Store remaining gas into a variable: `gas var_name`.
* Stop execution: `stop`. (will not cost gas)

## Deploying a contract

A contract is attached to a transaction when deployed, so to deploy a contract, simply create a transaction, paste the contract's code into the `to` property, put `SC` at the beginning of the code to show that this is a smart contract's code and send the transaction away.
A contract is attached to a transaction when deployed, so to deploy a contract, simply create a transaction, paste the contract's code into `<tx>.additionalData.scBody`, and then broadcast the transaction away.

```js
const myContract = `
Expand All @@ -104,41 +127,37 @@ const myContract = `
...
`;

const transaction = new Transaction(publicKey, "SC" + myContract, amount, gas);
const transaction = new Transaction(publicKey, "", amount, gas, {
scBody: myContract;
});

transaction.sign(keyPair);
Transaction.sign(transaction, keyPair);

sendTransaction(transaction);
```

## Triggering a contract

Just simply send a transaction to the contract address:
Just simply send a transaction to the contract address, also adding the contract execution gas in `Transaction.additionalData.contractGas`:
```js
const transaction = new Transaction(publicKey, "some contract address", amount, gas);
const transaction = new Transaction(publicKey, "some contract address", amount, gas, {
contractGas: someAmount
});

transaction.sign(keyPair);

sendTransaction(transaction);
```

You can call the contract with arguments by passing in an additional array to the `Transaction` constructor:
```js
const transaction = new Transaction(publicKey, "some contract address", amount, gas, ["arg1", "arg2", "arg3"]);
```

Note that all args are then stringified.

### Gas fee

To calculate gas fee, uses `calculateGasFee`:
You can call the contract with arguments by passing in an additional array to `Transaction.additionalData.args`:
```js
const gas = calculateGasFee(contractAddress, args, from_optional);
const transaction = new Transaction(publicKey, "some contract address", amount, gas, {
contractGas: someAmount,
args: [args, go, into, here]
});
```

If the gas provided in the transaction is not greater or equal to the gas calculated, the contract will not be triggered.

Note: This is not your transaction's gas fee, it is for paying the contract's fee, so you should be passing it into the transaction constructor as `amount`.
Note that all args should be strings and are then stringified.

## Example

Expand Down
94 changes: 21 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,87 +47,39 @@ node keygen.js

And it will generate a public key and a private key for you.

### Sync chain

Currently, an "agreed" JeChain chain hasn't existed yet, so you can either create a new chain by skipping this whole section, or sync a chain from someone you happen to know that runs a JeChain node using `requestChain`.
### Configure your node

In `./src/jenode.js`, at the bottom of the file, add:
In `config.json`, change the props for your needs:

```js
requestChain("Some JeChain node address");
{
"PORT": /*PORT that your node will run on, default is 3000*/,
"RPC_PORT": /*PORT that the RPC server will run on, default is 5000*/,
"PEERS": /*An array containing peers' address that the node will connect with, default is an empty array*/,
"MY_ADDRESS": /*A string containing the node's address, default is "localhost:3000"*/,
"PRIVATE_KEY": /*A string containing a private key*/,
"ENABLE_MINING": /*Leave true if you want to mine, default is false*/
"ENABLE_LOGGING": /*Leave true if you want to log out contract logs, default is false*/,
"ENABLE_RPC": /*Leave true if you want to run a RPC server, default is false*/,
"SYNC_FROM": /*A string containing an address to sync chain from*/,
"ENABLE_CHAIN_REQUEST": /*Leave true if you want to sync chain from others, default is false*/
}
```

### Configure your node

In the terminal, follow this template:
To see an example, `config.json` already has some data set for you to have a look at.

```sh
# PORT=Server's port (e.g: 3000) (default is 3000)
# PEERS=Addresses to connect to (e.g: ws://localhost:3001, ws://localhost:3002, ws://localhost:3003) (default is blank)
# MY_ADDRESS=Server's address: ws://your.ip.and:port (e.g: ws://192.168.100.2:3004) (default is ws://localhost:3000)
# PRIVATE_KEY=Your private key (default is a new randomly generated key)
# ENABLE_MINING=true if you want to mine, skip otherwise (default is blank)
# ENABLE_LOGGING=true if you want to log out contract messages, skip otherwise (default is blank)
### Running the node

# ENABLE_RPC=true if you want to run an RPC server, skip otherwise (default is blank)
# RPC_PORT=RPC server's port (e.g: 5000) (default is 5000)

# Start the node
node .
```

Use `set` on Windows to set variables.
After everything is all set, simply type `node .` to run the node.

### Interacting with the node through JSON-RPC apis

(This will require you to run an RPC server).

To properly interact with the node, you should use the JSON-RPC apis, especially if you are creating dapps.
This process will need you to run an RPC server, basically leave `true` in `ENABLE_RPC` in `config.json` to enable it.

[Check out docs for JSON-RPC APIs here.](./JSON-RPC.md)
To properly interact with the node, you should use the JSON-RPC apis, especially if you are creating dapps. To get started, check out [docs for JSON-RPC APIs here.](./JSON-RPC.md)

**Note: This feature is still in its early stages, things might change when a stable release is ready.**

### Using the node manually through code:

You can also just use manual functions in `./src/jenode.js`

Mine a block:
```js
mine();
```

Broadcast a transaction:
```js
sendTransaction(yourTransactionObject);
```

To create a transaction object, use `Transaction`:

```js
const tx = new Transaction(publicKey, "address to be sent to", amount, gas, [args_optional]);

// Sign the transaction
tx.sign(keyPair);
```

Request for a chain and its information from some address:
```js
requestChain("Some JeChain node address");
```

If you just want to set up a node that mines continuously (like most people would), use `loopMine`:
```js
loopMine(optionalDelayTime);
```

Note: `loopMine` is used by default when mining is enabled.

You can manually connect to a node using `connect`:
```js
connect("Some JeChain node address");
```

### Run JeChain node publicly

Just do some port-forwarding, drop your public IP + the port you forwarded in and you are set!
Expand Down Expand Up @@ -163,15 +115,11 @@ Note that this is an experimental project which is still under development, and

## Todos

* Fix bugs.
* Update chain sync.
* Implement a proof of stake protocol.
* Implement sharding.
* Integrate EVM into the chain?
* Use a proper database (preferably LevelDB).
* Refactor codes, or rewrite in another language entirely, preferably Rust.
* Port websocket to other p2p protocols.
* Update missing documentation.

Full todo list can be seen here: https://github.com/nguyenphuminh/JeChain/projects/2


## Support the project!
Expand Down
12 changes: 12 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"PORT": 5000,
"RPC_PORT": 3000,
"PEERS": [],
"MY_ADDRESS": "ws://localhost:5000",
"PRIVATE_KEY": "",
"ENABLE_MINING": false,
"ENABLE_LOGGING": false,
"ENABLE_RPC": false,
"SYNC_FROM": "",
"ENABLE_CHAIN_REQUEST": false
}
6 changes: 6 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const { startServer } = require("./src/node/server");
const config = require("./config.json");

(async () => {
await startServer(config);
})();
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "jechain",
"version": "0.13.1",
"version": "0.14.0",
"description": "Node for JeChain - an experimental smart contract blockchain network",
"main": "./src/jenode.js",
"main": "./index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
Expand All @@ -11,6 +11,7 @@
"dependencies": {
"elliptic": "^6.5.4",
"fastify": "^3.29.0",
"level": "^8.0.0",
"ws": "^8.2.3"
}
}
70 changes: 0 additions & 70 deletions src/block.js

This file was deleted.

Loading

0 comments on commit c5293a3

Please sign in to comment.