Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: dcb9/janus
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: qtumproject/janus
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.
Loading
Showing 942 changed files with 81,137 additions and 428,154 deletions.
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ingore testing components
/testing
/playground
/metamask
/https
/logs
/.vscode
/.idea
janusLogs.txt
36 changes: 36 additions & 0 deletions .github/workflows/docker-openzeppelin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This is a basic workflow to help you get started with Actions

name: Openzeppelin

# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [master]
pull_request:
branches: [master]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

- name: Pull openzeppelin
run: cd testing && make init

- name: Build test harness
run: cd testing && make build-openzeppelin

# Runs a single command using the runners shell
- name: Run openzeppelin truffle tests
run: make openzeppelin-docker-compose
34 changes: 34 additions & 0 deletions .github/workflows/docker-unit-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This is a basic workflow to help you get started with Actions

name: Unit tests

# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [master]
pull_request:
branches: [master]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

# Runs a single command using the runners shell
- name: Build docker image to run unit tests
run: make docker-build-unit-tests

# Runs a set of commands using the runners shell
- name: Run unit tests in docker
run: make docker-unit-tests
40 changes: 40 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -13,3 +13,43 @@
.idea

.DS_Store
build
node_modules
metamask/dist
https
janusLogs.txt

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# VS Code extension RestClient
api.rest

# Truffle test result files
truffle-pruned-output.json
truffle-result-output.json
output.json
testing/testing

.parcel-cache
playground/pet-shop-tutorial/dist
playground/pet-shop-tutorial/js/Adoption.json
playground/pet-shop-tutorial/js/Migrations.json
playground/pet-shop-tutorial/js/QRC20Token.json

3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "testing/openzeppelin-contracts"]
path = testing/openzeppelin/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts.git
75 changes: 75 additions & 0 deletions DIFFERENCES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Differences between EVM chains
- Transaction signing is incompatible
- QTUM is based on Bitcoin and therefore requires Bitcoin transaction signing
- EVM transactions are done with special opcodes in Bitcoin output scripts (OP_CALL/OP_CREATE)
- Use [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) to sign transactions for use in eth_sendRawTransaction
- Currently, the library only supports sending 1 tx per block due to Bitcoin inputs being re-used so test your code to redo transactions if they are rejected with eth_sendRawTransaction
- This will be fixed in a future version
- Solidity
- msg.value is denoted in satoshis, not wei, your dapp needs to handle this correctly
- eth_sign
- uses a different message prefix than Ethereum: "\u0015Qtum Signed Message:\n" (equal to "\x15Qtum Signed Message:\n")
- you will need to update your contracts to use this prefix
- ecrecover won't recover a QTUM address from eth_sign, you will need to implement [QIP6 - btc_ecrecover](https://blog.qtum.org/qip-6-87e7a9743e14) in your contracts
- [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) properly signs messages
- Sending coins with the creation of a contract will cause a loss of coins
- This is a Qtum intentional deisgn decision and will not change
- Janus will prevent this with eth_sendTransaction but will permit it with eth_sendRawTransaction
- [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) will reject creating such a transaction
- Contract address generation differs from EVM chains
- on EVM chains, the contract address is generated via a hash of the deployer address + the nonce
- QTUM has no concept of a nonce because it is built on Bitcoin
- instead the contract address is generated via a hash of the transaction which will always be different because the Bitcoin inputs will be different
- so, if your app depends on a consistent contract address between deployments on different chains you need to pay special attention to this
- For contract address generation code, see [generateContractAddress](https://github.com/earlgreytech/qtum-ethers/blob/main/src/lib/helpers/utils.ts)
- Account address generation differs from EVM chains
- You really only need to worry about this if you need to use the same account address on different chains
- [eth_accounts](pkg/transformer/eth_accounts.go) and [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) will abstract this away from you
- For account address generation code, see [computeAddress](https://github.com/earlgreytech/qtum-ethers/blob/main/src/lib/helpers/utils.ts)
- Block hash is computed differently from EVM chains
- If you are generating the blockhash from the block header, it will be wrong
- we plan to add a compatiblity layer in Janus to transparently serve the correct block when requesting an Ethereum block hash
- this will eventually require hooking up Janus to a database to keep a map of hash(block header) => QTUM block hash
- Remix
- Debug calls are not supported so you will not be able to do any debugging in Remix
- You can use Remix with Janus or [(Alpha) QTUM Metamask fork](https://github.com/earlgreytech/metamask-extension/releases)
- It is possible for a QTUM transaction to have more than one EVM transaction in it
- this is because QTUM does EVM transactions inside Bitcoin outputs which there can be multiple of
- Janus and [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) will not generate such a transaction
- Janus will try and work around such a transaction when requesting information about the transaction
- but it is not possible to map to the EVM model perfectly so there will always be some data missing for these transactions
- QTUM is proof of stake and requires coins to be mature (older than 2000 blocks) to be used in a transaction
- this includes staking rewards, gas refunds and block rewards on your local regtest environment
- a gas refund is an output generated by the miner for every EVM transaction in the same block as the EVM transaction takes place in for unused gas
- Janus will try to use mature coins first and will fall back to immature coins if there are no mature coins left
- this can result in transactions being rejected
- [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) will not use immature coins for transactions, but if you end up using high gas limits for your transactions you could quickly run out of usable coins
- if there are no mature coins, the transaction will fail locally
- Bitcoin input scripts
- Bitcoin has many different types of scripts
- For a detailed primer on this topic see [A breakdown of Bitcoin "standard" script types (crazy long)](https://www.reddit.com/r/Bitcoin/comments/jmiko9/a_breakdown_of_bitcoin_standard_script_types/)
- [eth_sendTransaction](/pkg/transformer/eth_sendTransaction.go) delegates transaction signing to QTUM so most input scripts should be supported
- [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) deals with signing transactions locally and only supports Pay to public key hash (P2PKH) scripts, other script types will be ignored and not selected.
- This can result in your spendable balance being lower than your actual balance.
- Support for Pay to public key (P2PK) input scripts is on the roadmap
- [eth_estimateGas](/pkg/transformer/eth_estimateGas.go)
- Gas estimation on QTUM is not perfect, so a buffer of 10% is added in Janus
- Gas will be refunded in the block that your transaction is mined
- Keep in mind that to re-use this gas refund, you must wait 2000 blocks
- [eth_sendTransaction](/pkg/transformer/eth_sendTransaction.go)
- When trying to send all your QTUM Balance in a transaction, in EVM you would do value = total - (gas limit * gas price)
- Since QTUM uses Bitcoin transactions, the cost of a transaction differs based on how many bytes are in the transaction
- This means if you have many inputs in a transaction, it will cost more to send
- There is no easy way to send your entire QTUM balance in a single transaction with Janus
- However, [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) supports this via value = total - (gas limit * gas price)
- Adding this to Janus is on the roadmap
- Since QTUM runs on Bitcoin, QTUM has the concept of [dust](https://en.bitcoinwiki.org/wiki/Cryptocurrency_dust)
- Janus delegates transaction signing to QTUM so QTUM will handle dealing with dust
- [(Beta) QTUM ethers-js library](https://github.com/earlgreytech/qtum-ethers) currently uses dust, but at some point will prevent spending dust by default with a semver change
- On a transfer of Qtum to a Qtum address, there is no receipt generated for such a transfer
- When converting from WEI -> QTUM, precision is lost due to QTUM's smallest demonination being 1 satoshi.
- 1 satoshi = 0.00000001 QTUM = 10000000000 wei
- QTUM's minimum gas price is 40 satoshi
- When specifying a gas price in wei lower than that, the minimum gas price will be used (40 satoshi)
- With the minimum fee per byte being 4 satoshi
- QTUM will reject transactions with very large fees (to prevent accidents)
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
ARG GO_VERSION=1.18
ARG ALPINE_VERSION=3.16

FROM golang:${GO_VERSION}-alpine as builder
RUN apk add --no-cache make gcc musl-dev git

WORKDIR $GOPATH/src/github.com/qtumproject/janus
COPY go.mod go.sum $GOPATH/src/github.com/qtumproject/janus/

# Cache go modules
RUN go mod download -x

ARG GIT_SHA
ENV CGO_ENABLED=0

COPY ./ $GOPATH/src/github.com/qtumproject/janus

ENV GIT_SHA=$GIT_SH

RUN go build \
-ldflags \
"-X 'github.com/qtumproject/janus/pkg/params.GitSha=`./sha.sh`'" \
-o $GOPATH/bin $GOPATH/src/github.com/qtumproject/janus/... && \
rm -fr $GOPATH/src/github.com/qtumproject/janus/.git

# Final stage
FROM alpine:${ALPINE_VERSION} as base
# Makefile supports generating ssl files from docker
RUN apk add --no-cache openssl
COPY --from=builder /go/bin/janus /janus

ENV QTUM_RPC=http://qtum:testpasswd@localhost:3889
ENV QTUM_NETWORK=auto

EXPOSE 23889
EXPOSE 23890

ENTRYPOINT [ "/janus" ]
Loading