Merge pull request #20 from VerusCoin/master

Reverse merge release into working fork
This commit is contained in:
miketout
2018-09-11 20:35:39 -07:00
committed by GitHub
175 changed files with 11061 additions and 3298 deletions

View File

@@ -1,41 +1,37 @@
stages:
- build
- test
- deploy
- build
- test
- deploy
variables:
VERSION: 0.3.10
AGAMA_ARTIFACTS_LINUX: linux64.tar.gz
AGAMA_ARTIFACTS_MACOS: osx.tar.gz
AGAMA_ARTIFACTS_WINDOWS: win64.zip
VERUS_CLI_DEBIAN: verus-cli-v${VERSION}-beta-amd64.deb
VERUS_CLI_LINUX_PORTABLE: verus-cli-linux-v$VERSION-beta.tar.gz
VERUS_CLI_WINDOWS_PORTABLE: verus-cli-windows-v$VERSION-beta.zip
VERUS_CLI_MACOS_PORTABLE: verus-cli-mac-v$VERSION-beta.tar.gz
VERSION: 0.3.13
VERUS_CLI_LINUX: "Verus-CLI-Linux-v${VERSION}-beta.tar.gz"
VERUS_CLI_WINDOWS: "Verus-CLI-Windows-v${VERSION}-beta.zip"
VERUS_CLI_MACOS: "Verus-CLI-MacOS-v${VERSION}-beta.tar.gz"
POST_COMMENT: "Branch and Commit: ${CI_COMMIT_REF_NAME} ${CI_COMMIT_SHA} $'\n'MD5: "
build:linux:
image: asherd/veruscoin-cross-compiler:linux
variables:
DOCKER_DRIVER: overlay2
stage: build
cache:
key: ${CI_JOB_NAME}
paths:
- depends/built
- .ccache
before_script: # Setup Cache
- rm -rf /root/.ccache || true
- mv .ccache /root/ || true
- rm -rf /root/.ccache || true
- mv .ccache /root/ || true
script:
- zcutil/build.sh -j4
- ./makeReleaseLinux.sh
- dos2unix kmd/linux/verus-cli/README.txt
- tar -C kmd/linux/ -czvf $VERUS_CLI_LINUX_PORTABLE verus-cli ./
- mv kmd/linux/verus-cli kmd/linux/linux64
- tar -C kmd/linux/ -czvf $AGAMA_ARTIFACTS_LINUX linux64 ./
- zcutil/build.sh -j4
- cp src/komodod src/komodo-cli kmd/linux/verus-cli
- chmod +x kmd/linux/verus-cli/komodod
- chmod +x kmd/linux/verus-cli/komodo-cli
- chmod +x kmd/linux/verus-cli/verus
- chmod +x kmd/linux/verus-cli/verusd
- chmod +x kmd/linux/verus-cli/fetch-params
- dos2unix kmd/linux/verus-cli/README.txt
- cd kmd/linux/
- tar -czvf $VERUS_CLI_LINUX verus-cli
- mv $VERUS_CLI_LINUX ../..
after_script:
- mv /root/.ccache ./ || true
- mv /root/.ccache ./ || true
cache:
key: ${CI_JOB_NAME}
paths:
@@ -43,8 +39,7 @@ build:linux:
- .ccache
artifacts:
paths:
- $VERUS_CLI_LINUX_PORTABLE
- $AGAMA_ARTIFACTS_LINUX
- $VERUS_CLI_LINUX
expire_in: 1 week
@@ -60,24 +55,19 @@ build:windows:
- .ccache
- .cargo
before_script:
- mkdir .ccache || echo ccache exists
- ln -s $PWD/.ccache /root/.ccache
- mkdir .zcash-params || echo zcash-params exists
- mkdir .cargo || echo .cargo exists
- ln -s $PWD/.cargo /root/.cargo
- mkdir .ccache || echo ccache exists
- ln -s $PWD/.ccache /root/.ccache
- mkdir .zcash-params || echo zcash-params exists
- mkdir .cargo || echo .cargo exists
- ln -s $PWD/.cargo /root/.cargo
script:
- zcutil/build-win.sh
- ./makeReleaseWindows.sh
- cd kmd/windows/
- zip -r $VERUS_CLI_WINDOWS_PORTABLE verus-cli
- mv $VERUS_CLI_WINDOWS_PORTABLE ../..
- mv verus-cli win64
- zip -r $AGAMA_ARTIFACTS_WINDOWS win64
- mv $AGAMA_ARTIFACTS_WINDOWS ../..
- zcutil/build-win.sh -j4
- cp src/komodod.exe src/komodo-cli.exe src/komodo-tx.exe kmd/windows/verus-cli
- cd kmd/windows/
- zip -r $VERUS_CLI_WINDOWS verus-cli
- mv $VERUS_CLI_WINDOWS ../..
artifacts:
paths:
- $VERUS_CLI_WINDOWS_PORTABLE
- $AGAMA_ARTIFACTS_WINDOWS
paths: [$VERUS_CLI_WINDOWS]
expire_in: 1 week
@@ -89,147 +79,159 @@ build:mac:
paths:
- depends/built
script:
- zcutil/build-mac.sh | xcpretty
- ./makeReleaseMac.sh
- dos2unix kmd/mac/verus-cli/README.txt
- tar -C kmd/mac/ -czvf $VERUS_CLI_MACOS_PORTABLE verus-cli ./
- mv kmd/mac/verus-cli kmd/mac/osx
- tar -C kmd/mac/ -czvf $AGAMA_ARTIFACTS_MACOS osx ./
- brew bundle
- zcutil/build-mac.sh -j6 | xcpretty
- ./makeReleaseMac.sh
- dos2unix kmd/mac/verus-cli/README.txt
- tar -C kmd/mac/ -czvf $VERUS_CLI_MACOS verus-cli ./
artifacts:
paths:
- $VERUS_CLI_MACOS_PORTABLE
- $AGAMA_ARTIFACTS_MACOS
paths: [$VERUS_CLI_MACOS]
expire_in: 1 week
code_quality:
.code_quality:
image: docker:stable
variables:
DOCKER_DRIVER: overlay2
allow_failure: true
services:
- docker:stable-dind
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [gl-code-quality-report.json]
sast:
.sast:
image: docker:stable
variables:
DOCKER_DRIVER: overlay2
allow_failure: true
services:
- docker:stable-dind
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SAST_CONFIDENCE_LEVEL="${SAST_CONFIDENCE_LEVEL:-3}"
--volume "$PWD:/code"
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/sast:$SP_VERSION" /app/bin/run /code
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SAST_CONFIDENCE_LEVEL="${SAST_CONFIDENCE_LEVEL:-3}"
--volume "$PWD:/code"
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/sast:$SP_VERSION" /app/bin/run /code
artifacts:
paths: [gl-sast-report.json]
license_management:
.license_management:
image: docker:stable
variables:
DOCKER_DRIVER: overlay2
allow_failure: true
services:
- docker:stable-dind
- docker:stable-dind
script:
- export LICENSE_MANAGEMENT_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--volume "$PWD:/code"
"registry.gitlab.com/gitlab-org/security-products/license-management:$LICENSE_MANAGEMENT_VERSION" analyze /code
- export LICENSE_MANAGEMENT_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--volume "$PWD:/code"
"registry.gitlab.com/gitlab-org/security-products/license-management:$LICENSE_MANAGEMENT_VERSION" analyze /code
artifacts:
paths: [gl-license-management-report.json]
ubuntu:xenial:
.ubuntu:xenial:
image: ubuntu:xenial
variables:
DOCKER_DRIVER: overlay2
stage: test
before_script:
- apt update && apt install -y wget g++-multilib libcurl3 python
- apt update && apt install -y wget g++-multilib libcurl3 python
- rm -rf /root/.komodo || true
- mv .komodo /root/ || true
script:
- tar -xzvf $VERUS_CLI_LINUX_PORTABLE
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
- tar -xzvf $VERUS_CLI_LINUX
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
after_script:
- mv /root/.komodo ./ || true
cache:
key: ${CI_JOB_NAME}
paths: [.komodo]
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:linux
- build:linux
ubuntu:bionic:
.ubuntu:bionic:
image: ubuntu:bionic
variables:
DOCKER_DRIVER: overlay2
stage: test
before_script:
- apt update && apt install -y wget g++-multilib libcurl3 python
- apt update && apt install -y wget g++-multilib libcurl3 python
- rm -rf /root/.komodo || true
- mv .komodo /root/ || true
script:
- tar -xzvf $VERUS_CLI_LINUX_PORTABLE
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
- tar -xzvf $VERUS_CLI_LINUX
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
after_script:
- mv /root/.komodo ./ || true
cache:
key: ${CI_JOB_NAME}
paths: [.komodo]
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:linux
- build:linux
.osx:sierra: # fetch-params.sh needs to be fixed for MacOS
stage: test
tags: ["Sierra"]
script:
- tar -xzvf $VERUS_CLI_MACOS_PORTABLE
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
- tar -xzvf $VERUS_CLI_MACOS
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:mac
- build:mac
.osx:high-sierra: # fetch-params.sh needs to be fixed for MacOS
stage: test
tags: ["High Sierra"]
script:
- tar -xzvf $VERUS_CLI_MACOS_PORTABLE
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
- tar -xzvf $VERUS_CLI_MACOS
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:mac
- build:mac
windows:10:
.windows:10:
stage: test
tags: ["Windows 10"]
script:
- PowerShell Expand-Archive -Path %VERUS_CLI_WINDOWS_PORTABLE% -DestinationPath %CI_PROJECT_DIR%
- set PATH=%PATH%;%CI_PROJECT_DIR%\verus-cli
- qa\verus-cli-tests\verus-cli-tester.py
- PowerShell Expand-Archive -Path %VERUS_CLI_WINDOWS% -DestinationPath %CI_PROJECT_DIR%
- set PATH=%PATH%;%CI_PROJECT_DIR%\verus-cli
- qa\verus-cli-tests\verus-cli-tester.py
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:windows
- build:windows
deploy:
@@ -238,18 +240,44 @@ deploy:
variables:
DOCKER_DRIVER: overlay2
dependencies:
- build:linux
- build:windows
- build:mac
- build:linux
- build:windows
- build:mac
before_script:
- export VERUS_CLI_LINUX_MD5=$(md5sum $VERUS_CLI_LINUX | cut -d " " -f 1)
- export VERUS_CLI_WINDOWS_MD5=$(md5sum $VERUS_CLI_WINDOWS | cut -d " " -f 1)
- export VERUS_CLI_MACOS_MD5=$(md5sum $VERUS_CLI_MACOS | cut -d " " -f 1)
script:
- mkdir -p $CI_COMMIT_REF_NAME/Windows
- mkdir -p $CI_COMMIT_REF_NAME/Linux
- mkdir -p $CI_COMMIT_REF_NAME/MacOS
- mv $VERUS_CLI_WINDOWS_PORTABLE $AGAMA_ARTIFACTS_WINDOWS $CI_COMMIT_REF_NAME/Windows
- mv $VERUS_CLI_LINUX_PORTABLE $AGAMA_ARTIFACTS_LINUX $CI_COMMIT_REF_NAME/Linux
- mv $VERUS_CLI_MACOS_PORTABLE $AGAMA_ARTIFACTS_MACOS $CI_COMMIT_REF_NAME/MacOS
- echo "$AUTH_KEY" > AUTH_KEY.json
- gcloud auth activate-service-account --key-file AUTH_KEY.json
- gsutil rsync -r $CI_COMMIT_REF_NAME/ $STAGING/VerusCoin/$CI_COMMIT_REF_NAME/
- export VERUS_CLI_LINUX_MD5=$(md5sum $VERUS_CLI_LINUX | cut -d " " -f 1)
- curl -F file=@"$VERUS_CLI_LINUX"
-F channels="$CLI_POST_CHANNEL"
-F initial_comment="${POST_COMMENT}$VERUS_CLI_LINUX_MD5"
-H "${SLACK_BOT_AUTH}"
"https://slack.com/api/files.upload"
- curl -F file=@"$VERUS_CLI_WINDOWS"
-F channels="$CLI_POST_CHANNEL"
-F initial_comment="${POST_COMMENT}$VERUS_CLI_WINDOWS_MD5"
-H "${SLACK_BOT_AUTH}"
"https://slack.com/api/files.upload"
- curl -F file=@"$VERUS_CLI_MACOS"
-F channels="$CLI_POST_CHANNEL"
-F initial_comment="${POST_COMMENT}$VERUS_CLI_MACOS_MD5"
-H "${SLACK_BOT_AUTH}"
"https://slack.com/api/files.upload"
- mkdir Windows && mkdir Linux && mkdir MacOS &&
mv $VERUS_CLI_WINDOWS Windows &&
mv $VERUS_CLI_LINUX Linux &&
mv $VERUS_CLI_MACOS MacOS
- echo "$AUTH_KEY" > AUTH_KEY.json &&
gcloud auth activate-service-account
--key-file AUTH_KEY.json
- gsutil cp -r Windows Linux MacOS $STAGING/VerusCoin/$CI_COMMIT_REF_NAME/
- curl -X POST
-F token="$CI_JOB_TOKEN"
-F ref=dev
-F variables\[UPSTREAM_CLI_BRANCH\]="$CI_COMMIT_REF_NAME"
-F variables\[VERUS_CLI_LINUX\]="$VERUS_CLI_LINUX"
-F variables\[VERUS_CLI_WINDOWS\]="$VERUS_CLI_WINDOWS"
-F variables\[VERUS_CLI_MACOS\]="$VERUS_CLI_MACOS"
"https://gitlab.com/api/v4/projects/8018592/trigger/pipeline"

View File

@@ -9,7 +9,7 @@ brew "automake"
brew "binutils"
brew "cmake"
brew "coreutils"
brew "gcc@5"
brew "gcc@6"
brew "leveldb"
brew "nanomsg"
brew "protobuf"

View File

@@ -1,3 +1,4 @@
Copyright (c) 2016-2018 The Komodo developers
Copyright (c) 2016-2017 The Zcash developers
Copyright (c) 2009-2017 The Bitcoin Core developers
Copyright (c) 2018 The VerusCoin developers

View File

@@ -1,4 +1,5 @@
First off you need Apple's Xcode (at least version 7, preferably 8.x) and the Xcode Command Line Tools:
You will need Apple's Xcode (at least version 7, preferably 8.x) and the Xcode Command Line Tools:
https://itunes.apple.com/us/app/xcode/id497799835?mt=12
@@ -6,23 +7,50 @@ And Homebrew:
http://brew.sh/
then use the brewfile to install the necessary packages:
Use the brewfile to install the necessary packages:
```shell
brew bundle
```
or
```shell
brew tap discoteq/discoteq; brew install flock autoconf autogen automake gcc@6 binutils protobuf coreutils wget
```
Get all that installed, then run:
```shell
git clone https://github.com/VerusCoin/VerusCoin.git
cd VerusCoin
./zcutil/build-mac.sh
./zcutil/fetch-params.sh
```
To build a distributable version of VerusCoin then run the makeReleaseMac.sh script after building. This will fix the dependency references and move the komodod and komodo-cli binaries to the kmd/mac/verus-cli directory along with the 6 libraries required for it to work properly.
When you are done building, you need to do a few things in the [Configuration](https://github.com/zcash/zcash/wiki/1.0-User-Guide#configuration) section of the Zcash User Guide differently because we are on the Mac. All instances of `~/.zcash` need to be replaced by `~/Library/Application\ Support/Zcash`
The fetch-params.sh script, however, has already been altered to fetch the proving keys into the correct directory to conform to Mac specific naming conventions.
When you are done building, you need to create `Komodo.conf` the Mac way.
```shell
mkdir ~/Library/Application\ Support/Komodo
touch ~/Library/Application\ Support/Komodo/Komodo.conf
nano ~/Library/Application\ Support/Komodo/Komodo.conf
```
Add the following lines to the Komodo.conf file:
```shell
rpcuser=dontuseweakusernameoryougetrobbed
rpcpassword=dontuseweakpasswordoryougetrobbed
txindex=1
addnode=5.9.102.210
addnode=78.47.196.146
addnode=178.63.69.164
addnode=88.198.65.74
addnode=5.9.122.241
addnode=144.76.94.38
addnode=89.248.166.91
```
Happy Building

View File

@@ -1,8 +1,11 @@
## VerusCoin version 0.3.10-beta
## VerusCoin version 0.3.13-beta
VerusCoin is a new, mineable and stakeable cryptocurrency. It is a live fork of Komodo that retains its Zcash lineage and improves it. VerusCoin will leverage the Komodo platform and dPoW notarization for enhanced security and cross-chain interoperability. We have added a variation of a zawy12, lwma difficulty algorithm, a new CPU-optimized hash algorithm and a new algorithm for fair proof of stake. We describe these changes and vision going forward in a [our Phase I white paper](http://185.25.51.16/papers/VerusPhaseI.pdf) and [our Vision](http://185.25.51.16/papers/VerusVision.pdf).
- [VerusCoin web site https://veruscoin.io/ Wallets and CLI tools](https://veruscoin.io/)
- [VerusCoin Explorer](https://explorer.veruscoin.io/)
Version 0.3.13-beta has portable mining working.
## Komodo with Bitcore
This version of Komodo contains Bitcore support for komodo and all its assetchains.
@@ -19,7 +22,7 @@ The wallet downloads and stores the block chain or asset chain of the coin you s
- Support: [https://support.komodoplatform.com/support/home](https://support.komodoplatform.com/support/home)
- Knowledgebase & How-to: [https://komodoplatform.atlassian.net/wiki/spaces/KPSD/pages](https://komodoplatform.atlassian.net/wiki/spaces/KPSD/pages)
- API references: [http://docs.supernet.org/](http://docs.supernet.org/) #Not up to date.
- Whitepaper: [Komodo Whitepaper](https://komodoplatform.com/wp-content/uploads/2018/03/2018-03-12-Komodo-White-Paper-Full.pdf)
- Whitepaper: [Komodo Whitepaper](https://komodoplatform.com/wp-content/uploads/2018/06/Komodo-Whitepaper-June-3.pdf)
- Komodo Platform public material: [Komodo Platform public material](https://docs.google.com/document/d/1AbhWrtagu4vYdkl-vsWz-HSNyNvK-W-ZasHCqe7CZy0)
## List of Komodo Platform Technologies

View File

@@ -0,0 +1,140 @@
##
## komodo.conf configuration file. Lines beginning with # are comments.
##
# Network-related settings:
# Run a regression test network
#regtest=0
# Connect via a SOCKS5 proxy
#proxy=127.0.0.1:9050
# Bind to given address and always listen on it. Use [host]:port notation for IPv6
#bind=<addr>
# Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6
#whitebind=<addr>
##############################################################
## Quick Primer on addnode vs connect ##
## Let's say for instance you use addnode=4.2.2.4 ##
## addnode will connect you to and tell you about the ##
## nodes connected to 4.2.2.4. In addition it will tell ##
## the other nodes connected to it that you exist so ##
## they can connect to you. ##
## connect will not do the above when you 'connect' to it. ##
## It will *only* connect you to 4.2.2.4 and no one else.##
## ##
## So if you're behind a firewall, or have other problems ##
## finding nodes, add some using 'addnode'. ##
## ##
## If you want to stay private, use 'connect' to only ##
## connect to "trusted" nodes. ##
## ##
## If you run multiple nodes on a LAN, there's no need for ##
## all of them to open lots of connections. Instead ##
## 'connect' them all to one node that is port forwarded ##
## and has lots of connections. ##
## Thanks goes to [Noodle] on Freenode. ##
##############################################################
# Use as many addnode= settings as you like to connect to specific peers
#addnode=69.164.218.197
#addnode=10.0.0.2:8233
# Alternatively use as many connect= settings as you like to connect ONLY to specific peers
#connect=69.164.218.197
#connect=10.0.0.1:8233
# Listening mode, enabled by default except when 'connect' is being used
#listen=1
# Maximum number of inbound+outbound connections.
#maxconnections=
#
# JSON-RPC options (for controlling a running Komodo/komodod process)
#
# server=1 tells komodod to accept JSON-RPC commands (set as default if not specified)
#server=1
# Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6.
# This option can be specified multiple times (default: bind to all interfaces)
#rpcbind=<addr>
# You must set rpcuser and rpcpassword to secure the JSON-RPC api
#rpcuser=Ulysses
#rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593
# How many seconds komodo will wait for a complete RPC HTTP request.
# after the HTTP connection is established.
#rpcclienttimeout=30
# By default, only RPC connections from localhost are allowed.
# Specify as many rpcallowip= settings as you like to allow connections from other hosts,
# either as a single IPv4/IPv6 or with a subnet specification.
# NOTE: opening up the RPC port to hosts outside your local trusted network is NOT RECOMMENDED,
# because the rpcpassword is transmitted over the network unencrypted and also because anyone
# that can authenticate on the RPC port can steal your keys + take over the account running komodod
# For more information see https://github.com/zcash/zcash/issues/1497
#rpcallowip=10.1.1.34/255.255.255.0
#rpcallowip=1.2.3.4/24
#rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96
# Listen for RPC connections on this TCP port:
#rpcport=8232
# You can use Komodo or komodod to send commands to Komodo/komodod
# running on another host using this option:
#rpcconnect=127.0.0.1
# Transaction Fee
# Send transactions as zero-fee transactions if possible (default: 0)
#sendfreetransactions=0
# Create transactions that have enough fees (or priority) so they are likely to # begin confirmation within n blocks (default: 1).
# This setting is overridden by the -paytxfee option.
#txconfirmtarget=n
# Miscellaneous options
# Enable attempt to mine komodo.
#gen=0
# Set the number of threads to be used for mining komodo (-1 = all cores).
#genproclimit=1
# Specify a different Equihash solver (e.g. "tromp") to try to mine komodo
# faster when gen=1.
#equihashsolver=default
# Pre-generate this many public/private key pairs, so wallet backups will be valid for
# both prior transactions and several dozen future transactions.
#keypool=100
# Pay an optional transaction fee every time you send komodo. Transactions with fees
# are more likely than free transactions to be included in generated blocks, so may
# be validated sooner. This setting does not affect private transactions created with
# 'z_sendmany'.
#paytxfee=0.00
#Rewind the chain to specific block height. This is useful for creating snapshots at a given block height.
#rewind=777777
#Stop the chain a specific block height. This is useful for creating snapshots at a given block height.
#stopat=1000000
#Set an address to use as change address for all transactions. This value must be set to a 33 byte pubkey. All mined coins will also be sent to this address.
#pubkey=027dc7b5cfb5efca96674b45e9fda18df069d040b9fd9ff32c35df56005e330392
#Forfeit all user rewards to miners. Set this to explicitly not claim user rewards.
#exchange=1
#Donate all user rewards to a a specific address. This value must be set to a 33 byte pubkey.
#donation=027dc7b5cfb5efca96674b45e9fda18df069d040b9fd9ff32c35df56005e330392

View File

@@ -1,879 +1,6 @@
1.34.168.128:8333
1.202.128.218:8333
2.30.0.210:8333
5.9.96.203:8333
5.45.71.130:8333
5.45.98.141:8333
5.102.145.68:8333
5.135.160.77:8333
5.189.134.246:8333
5.199.164.132:8333
5.249.135.102:8333
8.19.44.110:8333
8.22.230.8:8333
14.200.200.145:8333
18.228.0.188:8333
18.228.0.200:8333
23.24.168.97:8333
23.28.35.227:8333
23.92.76.170:8333
23.99.64.119:8333
23.228.166.128:8333
23.229.45.32:8333
24.8.105.128:8333
24.16.69.137:8333
24.94.98.96:8333
24.102.118.7:8333
24.118.166.228:8333
24.122.133.49:8333
24.166.97.162:8333
24.213.235.242:8333
24.226.107.64:8333
24.228.192.171:8333
27.140.133.18:8333
31.41.40.25:8333
31.43.101.59:8333
31.184.195.181:8333
31.193.139.66:8333
37.200.70.102:8333
37.205.10.151:8333
42.3.106.227:8333
42.60.133.106:8333
45.56.85.231:8333
45.56.102.228:8333
45.79.130.235:8333
46.28.204.61:11101
46.38.235.229:8333
46.59.2.74:8333
46.101.132.37:8333
46.101.168.50:8333
46.163.76.230:8333
46.166.161.103:8333
46.182.132.100:8333
46.223.36.94:8333
46.227.66.132:8333
46.227.66.138:8333
46.239.107.74:8333
46.249.39.100:8333
46.250.98.108:8333
50.7.37.114:8333
50.81.53.151:8333
50.115.43.253:8333
50.116.20.87:8333
50.116.33.92:8333
50.125.167.245:8333
50.143.9.51:8333
50.188.192.133:8333
54.77.162.76:8333
54.153.97.109:8333
54.165.192.125:8333
58.96.105.85:8333
59.167.196.135:8333
60.29.227.163:8333
61.35.225.19:8333
62.43.130.178:8333
62.109.49.26:8333
62.202.0.97:8333
62.210.66.227:8333
62.210.192.169:8333
64.74.98.205:8333
64.156.193.100:8333
64.203.102.86:8333
64.229.142.48:8333
65.96.193.165:8333
66.30.3.7:8333
66.114.33.49:8333
66.118.133.194:8333
66.135.10.126:8333
66.172.10.4:8333
66.194.38.250:8333
66.194.38.253:8333
66.215.192.104:8333
67.60.98.115:8333
67.164.35.36:8333
67.191.162.244:8333
67.207.195.77:8333
67.219.233.140:8333
67.221.193.55:8333
67.228.162.228:8333
68.50.67.199:8333
68.62.3.203:8333
68.65.205.226:9000
68.106.42.191:8333
68.150.181.198:8333
68.196.196.106:8333
68.224.194.81:8333
69.46.5.194:8333
69.50.171.238:8333
69.64.43.152:8333
69.65.41.13:8333
69.90.132.200:8333
69.143.1.243:8333
69.146.98.216:8333
69.165.246.38:8333
69.207.6.135:8333
69.251.208.26:8333
70.38.1.101:8333
70.38.9.66:8333
70.90.2.18:8333
71.58.228.226:8333
71.199.11.189:8333
71.199.193.202:8333
71.205.232.181:8333
71.236.200.162:8333
72.24.73.186:8333
72.52.130.110:8333
72.53.111.37:8333
72.235.38.70:8333
73.31.171.149:8333
73.32.137.72:8333
73.137.133.238:8333
73.181.192.103:8333
73.190.2.60:8333
73.195.192.137:8333
73.222.35.117:8333
74.57.199.180:8333
74.82.233.205:8333
74.85.66.82:8333
74.101.224.127:8333
74.113.69.16:8333
74.122.235.68:8333
74.193.68.141:8333
74.208.164.219:8333
75.100.37.122:8333
75.145.149.169:8333
75.168.34.20:8333
76.20.44.240:8333
76.100.70.17:8333
76.168.3.239:8333
76.186.140.103:8333
77.92.68.221:8333
77.109.101.142:8333
77.110.11.86:8333
77.242.108.18:8333
78.46.96.150:9020
78.84.100.95:8333
79.132.230.144:8333
79.133.43.63:8333
79.160.76.153:8333
79.169.34.24:8333
79.188.7.78:8333
80.217.226.25:8333
80.223.100.179:8333
80.240.129.221:8333
81.1.173.243:8333
81.7.11.50:8333
81.7.16.17:8333
81.66.111.3:8333
81.80.9.71:8333
81.140.43.138:8333
81.171.34.37:8333
81.174.247.50:8333
81.181.155.53:8333
81.184.5.253:8333
81.187.69.130:8333
81.230.3.84:8333
82.42.128.51:8333
82.74.226.21:8333
82.142.75.50:8333
82.199.102.10:8333
82.200.205.30:8333
82.221.108.21:8333
82.221.128.35:8333
82.238.124.41:8333
82.242.0.245:8333
83.76.123.110:8333
83.150.9.196:8333
83.162.196.192:8333
83.162.234.224:8333
83.170.104.91:8333
83.255.66.118:8334
84.2.34.104:8333
84.45.98.91:8333
84.47.161.150:8333
84.212.192.131:8333
84.215.169.101:8333
84.238.140.176:8333
84.245.71.31:8333
85.17.4.212:8333
85.114.128.134:8333
85.159.237.191:8333
85.166.130.189:8333
85.199.4.228:8333
85.214.66.168:8333
85.214.195.210:8333
85.229.0.73:8333
86.21.96.45:8333
87.48.42.199:8333
87.81.143.82:8333
87.81.251.72:8333
87.104.24.185:8333
87.104.168.104:8333
87.117.234.71:8333
87.118.96.197:8333
87.145.12.57:8333
87.159.170.190:8333
88.150.168.160:8333
88.208.0.79:8333
88.208.0.149:8333
88.214.194.226:8343
89.1.11.32:8333
89.36.235.108:8333
89.67.96.2:15321
89.98.16.41:8333
89.108.72.195:8333
89.156.35.157:8333
89.163.227.28:8333
89.212.33.237:8333
89.212.160.165:8333
89.231.96.83:8333
89.248.164.64:8333
90.149.193.199:8333
91.77.239.245:8333
91.106.194.97:8333
91.126.77.77:8333
91.134.38.195:8333
91.156.97.181:8333
91.207.68.144:8333
91.209.77.101:8333
91.214.200.205:8333
91.220.131.242:8333
91.220.163.18:8333
91.233.23.35:8333
92.13.96.93:8333
92.14.74.114:8333
92.27.7.209:8333
92.221.228.13:8333
92.255.207.73:8333
93.72.167.148:8333
93.74.163.234:8333
93.123.174.66:8333
93.152.166.29:8333
93.181.45.188:8333
94.19.12.244:8333
94.190.227.112:8333
94.198.135.29:8333
94.224.162.65:8333
94.226.107.86:8333
94.242.198.161:8333
95.31.10.209:8333
95.65.72.244:8333
95.84.162.95:8333
95.90.139.46:8333
95.183.49.27:8005
95.215.47.133:8333
96.23.67.85:8333
96.44.166.190:8333
97.93.225.74:8333
98.26.0.34:8333
98.27.225.102:8333
98.229.117.229:8333
98.249.68.125:8333
98.255.5.155:8333
99.101.240.114:8333
101.100.174.138:8333
101.251.203.6:8333
103.3.60.61:8333
103.30.42.189:8333
103.224.165.48:8333
104.36.83.233:8333
104.37.129.22:8333
104.54.192.251:8333
104.128.228.252:8333
104.128.230.185:8334
104.130.161.47:8333
104.131.33.60:8333
104.143.0.156:8333
104.156.111.72:8333
104.167.111.84:8333
104.193.40.248:8333
104.197.7.174:8333
104.197.8.250:8333
104.223.1.133:8333
104.236.97.140:8333
104.238.128.214:8333
104.238.130.182:8333
106.38.234.84:8333
106.185.36.204:8333
107.6.4.145:8333
107.150.2.6:8333
107.150.40.234:8333
107.155.108.130:8333
107.161.182.115:8333
107.170.66.231:8333
107.190.128.226:8333
107.191.106.115:8333
108.16.2.61:8333
109.70.4.168:8333
109.162.35.196:8333
109.163.235.239:8333
109.190.196.220:8333
109.191.39.60:8333
109.234.106.191:8333
109.238.81.82:8333
114.76.147.27:8333
115.28.224.127:8333
115.68.110.82:18333
118.97.79.218:8333
118.189.207.197:8333
119.228.96.233:8333
120.147.178.81:8333
121.41.123.5:8333
121.67.5.230:8333
122.107.143.110:8333
123.2.170.98:8333
123.110.65.94:8333
123.193.139.19:8333
125.239.160.41:8333
128.101.162.193:8333
128.111.73.10:8333
128.140.229.73:8333
128.175.195.31:8333
128.199.107.63:8333
128.199.192.153:8333
128.253.3.193:20020
129.123.7.7:8333
130.89.160.234:8333
131.72.139.164:8333
131.191.112.98:8333
133.1.134.162:8333
134.19.132.53:8333
137.226.34.42:8333
141.41.2.172:8333
141.255.128.204:8333
142.217.12.106:8333
143.215.129.126:8333
146.0.32.101:8337
147.229.13.199:8333
149.210.133.244:8333
149.210.162.187:8333
150.101.163.241:8333
151.236.11.189:8333
153.121.66.211:8333
154.20.2.139:8333
159.253.23.132:8333
162.209.106.123:8333
162.210.198.184:8333
162.218.65.121:8333
162.222.161.49:8333
162.243.132.6:8333
162.243.132.58:8333
162.248.99.164:53011
162.248.102.117:8333
163.158.35.110:8333
164.15.10.189:8333
164.40.134.171:8333
166.230.71.67:8333
167.160.161.199:8333
168.103.195.250:8333
168.144.27.112:8333
168.158.129.29:8333
170.75.162.86:8333
172.90.99.174:8333
172.245.5.156:8333
173.23.166.47:8333
173.32.11.194:8333
173.34.203.76:8333
173.171.1.52:8333
173.175.136.13:8333
173.230.228.139:8333
173.247.193.70:8333
174.49.132.28:8333
174.52.202.72:8333
174.53.76.87:8333
174.109.33.28:8333
176.28.12.169:8333
176.35.182.214:8333
176.36.33.113:8333
176.36.33.121:8333
176.58.96.173:8333
176.121.76.84:8333
178.62.70.16:8333
178.62.111.26:8333
178.76.169.59:8333
178.79.131.32:8333
178.162.199.216:8333
178.175.134.35:8333
178.248.111.4:8333
178.254.1.170:8333
178.254.34.161:8333
179.43.143.120:8333
179.208.156.198:8333
180.200.128.58:8333
183.78.169.108:8333
183.96.96.152:8333
184.68.2.46:8333
184.73.160.160:8333
184.94.227.58:8333
184.152.68.163:8333
185.7.35.114:8333
185.28.76.179:8333
185.31.160.202:8333
185.45.192.129:8333
185.66.140.15:8333
186.2.167.23:8333
186.220.101.142:8333
188.26.5.33:8333
188.75.136.146:8333
188.120.194.140:8333
188.121.5.150:8333
188.138.0.114:8333
188.138.33.239:8333
188.166.0.82:8333
188.182.108.129:8333
188.191.97.208:8333
188.226.198.102:8001
190.10.9.217:8333
190.75.143.144:8333
190.139.102.146:8333
191.237.64.28:8333
192.3.131.61:8333
192.99.225.3:8333
192.110.160.122:8333
192.146.137.1:8333
192.183.198.204:8333
192.203.228.71:8333
193.0.109.3:8333
193.12.238.204:8333
193.91.200.85:8333
193.234.225.156:8333
194.6.233.38:8333
194.63.143.136:8333
194.126.100.246:8333
195.134.99.195:8333
195.159.111.98:8333
195.159.226.139:8333
195.197.175.190:8333
198.48.199.108:8333
198.57.208.134:8333
198.57.210.27:8333
198.62.109.223:8333
198.167.140.8:8333
198.167.140.18:8333
199.91.173.234:8333
199.127.226.245:8333
199.180.134.116:8333
200.7.96.99:8333
201.160.106.86:8333
202.55.87.45:8333
202.60.68.242:8333
202.60.69.232:8333
202.124.109.103:8333
203.30.197.77:8333
203.88.160.43:8333
203.151.140.14:8333
203.219.14.204:8333
205.147.40.62:8333
207.235.39.214:8333
207.244.73.8:8333
208.12.64.225:8333
208.76.200.200:8333
209.40.96.121:8333
209.126.107.176:8333
209.141.40.149:8333
209.190.75.59:8333
209.208.111.142:8333
210.54.34.164:8333
211.72.66.229:8333
212.51.144.42:8333
212.112.33.157:8333
212.116.72.63:8333
212.126.14.122:8333
213.66.205.194:8333
213.111.196.21:8333
213.122.107.102:8333
213.136.75.175:8333
213.155.7.24:8333
213.163.64.31:8333
213.163.64.208:8333
213.165.86.136:8333
213.184.8.22:8333
216.15.78.182:8333
216.55.143.154:8333
216.115.235.32:8333
216.126.226.166:8333
216.145.67.87:8333
216.169.141.169:8333
216.249.92.230:8333
216.250.138.230:8333
217.20.171.43:8333
217.23.2.71:8333
217.23.2.242:8333
217.25.9.76:8333
217.40.226.169:8333
217.123.98.9:8333
217.155.36.62:8333
217.172.32.18:20993
218.61.196.202:8333
218.231.205.41:8333
220.233.77.200:8333
223.18.226.85:8333
223.197.203.82:8333
223.255.166.142:8333
[2001:1291:2bf:1::100]:8333
[2001:1418:100:5c2::2]:8333
[2001:16d8:dd24:0:86c9:681e:f931:256]:8333
[2001:19f0:1624:e6::579d:9428]:8333
[2001:19f0:300:1340:225:90ff:fec9:2b6d]:8333
[2001:19f0:4009:1405::64]:8333
[2001:1b40:5000:2e::3fb0:6571]:8333
[2001:410:a000:4050:8463:90b0:fffb:4e58]:8333
[2001:410:a002:cafe:8463:90b0:fffb:4e58]:8333
[2001:41d0:1:541e::1]:8333
[2001:41d0:1:6a34::3]:8333
[2001:41d0:1:6cd3::]:8333
[2001:41d0:1:8b26::1]:8333
[2001:41d0:1:a33d::1]:8333
[2001:41d0:1:b855::1]:8333
[2001:41d0:1:c139::1]:8333
[2001:41d0:1:c8d7::1]:8333
[2001:41d0:1:dd3f::1]:8333
[2001:41d0:1:e29d::1]:8333
[2001:41d0:1:f59f::33]:8333
[2001:41d0:1:f7cc::1]:8333
[2001:41d0:1:ff87::1]:8333
[2001:41d0:2:2f05::1]:8333
[2001:41d0:2:37c3::]:8200
[2001:41d0:2:3e13::1]:8333
[2001:41d0:2:8619::]:8333
[2001:41d0:2:9c94::1]:8333
[2001:41d0:2:a24f::]:8333
[2001:41d0:2:adbf::]:8333
[2001:41d0:2:b721::1]:8333
[2001:41d0:2:ee52::1]:8333
[2001:41d0:2:f1a5::]:8333
[2001:41d0:2:fa54::1]:8333
[2001:41d0:51:1::2036]:8333
[2001:41d0:52:a00::1a1]:8333
[2001:41d0:52:cff::6f5]:8333
[2001:41d0:52:d00::2c0]:8333
[2001:41d0:52:d00::cf2]:8333
[2001:41d0:8:1087::1]:8333
[2001:41d0:8:4a3c::b7c]:8333
[2001:41d0:8:6728::]:8333
[2001:41d0:8:b779::1]:8333
[2001:41d0:8:c30f::1]:8333
[2001:41d0:8:d2b2::1]:8333
[2001:41d0:8:d5c3::1]:8333
[2001:41d0:8:eb8b::]:8333
[2001:41d0:a:16d0::1]:8333
[2001:41d0:a:2b18::1]:8333
[2001:41d0:a:3a9c::1]:8333
[2001:41d0:a:4903::]:8333
[2001:41d0:a:57b::1]:8333
[2001:41d0:a:5c7a::]:8333
[2001:41d0:a:6c29::1]:8333
[2001:41d0:a:f482::1]:8333
[2001:41d0:b:854:b7c:b7c:b7c:b7c]:8333
[2001:41d0:d:111c::]:8333
[2001:44b8:4116:7801:4216:7eff:fe78:3fe4]:8333
[2001:470:1f08:837::2]:8333
[2001:470:1f08:c33::2]:8333
[2001:470:1f09:bca:218:7dff:fe10:be33]:8333
[2001:470:1f0f:22d::212:26]:8333
[2001:470:1f11:12d5::ae1:5611]:8333
[2001:470:1f14:57a::2]:8333
[2001:470:1f14:7d::2]:8333
[2001:470:1f15:57c::1]:8333
[2001:470:1f15:dda:3d9a:3f11:9a56:ed64]:8333
[2001:470:25:482::2]:8333
[2001:470:25:e4::2]:8333
[2001:470:4:26b::2]:8333
[2001:470:5f:5f::232]:8333
[2001:470:66:119::2]:8333
[2001:470:67:39d::71]:8333
[2001:470:6c4f::cafe]:8333
[2001:470:8:2e1::43]:8333
[2001:470:90a7:96::afe:6021]:8333
[2001:470:95c1::2]:8333
[2001:470:b1d0:ffff::1000]:8333
[2001:470:c1f2:3::201]:8333
[2001:470:d00d:0:3664:a9ff:fe9a:5150]:8333
[2001:470:e250:0:211:11ff:feb9:924c]:8333
[2001:4800:7817:101:be76:4eff:fe04:dc52]:8333
[2001:4800:7819:104:be76:4eff:fe04:7809]:8333
[2001:4800:7819:104:be76:4eff:fe05:c828]:8333
[2001:4802:7800:2:30d7:1775:ff20:1858]:8333
[2001:4802:7802:101:be76:4eff:fe20:256]:8333
[2001:4802:7802:103:be76:4eff:fe20:2de8]:8333
[2001:4830:1100:2e8::2]:8333
[2001:4ba0:fff7:181:dead::1]:8333
[2001:4ba0:fffa:5d::93]:8333
[2001:4ba0:ffff:1be:1:1005:0:1]:8335
[2001:4c48:110:101:216:3eff:fe24:1162]:8333
[2001:4dd0:f101::32]:8333
[2001:4dd0:ff00:867f::3]:8333
[2001:4dd0:ff00:9a67::9]:8333
[2001:4dd0:ff00:9c55:c23f:d5ff:fe6c:7ee9]:8333
[2001:5c0:1400:b::3cc7]:8333
[2001:5c0:1400:b::3d01]:8333
[2001:5c0:1400:b::8df]:8333
[2001:5c0:1501:300::3]:8333
[2001:610:1b19::3]:8333
[2001:620:500:fff0:f21f:afff:fecf:91cc]:8333
[2001:67c:1220:80c:ad:8de2:f7e2:c784]:8333
[2001:67c:21ec:1000::b]:8333
[2001:6f8:1296:0:76d4:35ff:feba:1d26]:8333
[2001:840:f000:4250:3e4a:92ff:fe6d:145f]:8333
[2001:8d8:840:500::39:1ae]:8333
[2001:980:efd8:0:21:de4a:2709:912]:8333
[2001:981:46:1::3]:8333
[2001:981:9319:2:c0:a8:c8:8]:8333
[2001:9d8:cafe:3::91]:8333
[2001:ad0:1:1:26be:5ff:fe25:959d]:8333
[2001:ba8:1f1:f34c::2]:8333
[2001:bc8:381c:100::1]:8333
[2002:175c:4caa::175c:4caa]:8333
[2002:4404:82f1:0:8d55:8fbb:15fa:f4e0]:8333
[2002:4475:2233:0:21f:5bff:fe33:9f70]:8333
[2002:596c:48c3::596c:48c3]:8333
[2002:8c6d:6521:9617:12bf:48ff:fed8:1724]:8333
[2002:a646:5e6a::1:2]:8333
[2002:b009:20c5::b009:20c5]:8333
[2400:8900::f03c:91ff:fe6e:823e]:8333
[2400:8900::f03c:91ff:fe70:d164]:8333
[2400:8901::f03c:91ff:fe37:9761]:8333
[2403:4200:403:2::ff]:8333
[2403:b800:1000:64:40a:e9ff:fe5f:94c1]:8333
[2403:b800:1000:64:9879:17ff:fe6a:a59f]:8333
[2600:3c00::f03c:91ff:fe18:59b2]:8333
[2600:3c00::f03c:91ff:fe37:a4b1]:8333
[2600:3c00::f03c:91ff:fe56:2973]:8333
[2600:3c00::f03c:91ff:fe6e:7297]:8333
[2600:3c00::f03c:91ff:fe84:8a6e]:8333
[2600:3c01::f03c:91ff:fe18:6adf]:8333
[2600:3c01::f03c:91ff:fe18:e217]:8333
[2600:3c01::f03c:91ff:fe33:1b31]:8333
[2600:3c01::f03c:91ff:fe33:2fe1]:8333
[2600:3c01::f03c:91ff:fe33:a03f]:8333
[2600:3c01::f03c:91ff:fe50:5e06]:8333
[2600:3c01::f03c:91ff:fe56:d645]:8333
[2600:3c01::f03c:91ff:fe6e:a3dc]:8333
[2600:3c01::f03c:91ff:fe89:a659]:8333
[2600:3c02::f03c:91ff:fe6e:6f0b]:8333
[2600:3c03::f03c:91ff:fe33:f6fb]:8333
[2600:3c03::f03c:91ff:fe50:5fa7]:8333
[2600:3c03::f03c:91ff:fe6e:1803]:8333
[2600:3c03::f03c:91ff:fe6e:4ac0]:8333
[2601:6:4800:47f:1e4e:1f4d:332c:3bf6]:8333
[2601:d:5400:fed:8d54:c1e8:7ed7:d45e]:8333
[2602:100:4b8f:6d2a:20c:29ff:feaf:c4c2]:8333
[2602:ffc5:1f::1f:2d61]:8333
[2602:ffc5:1f::1f:9211]:8333
[2602:ffc5::ffc5:b844]:8333
[2602:ffe8:100:2::457:936b]:8333
[2602:ffea:1001:125::2ad4]:8333
[2602:ffea:1001:6ff::837d]:8333
[2602:ffea:1001:72b::578b]:8333
[2602:ffea:1001:77a::9cae]:8333
[2602:ffea:1:2fe::6bc8]:8333
[2602:ffea:1:701::7968]:8333
[2602:ffea:1:70d::82ec]:8333
[2602:ffea:1:9ff::e957]:8333
[2602:ffea:1:a5d::4acb]:8333
[2602:ffea:a::24c4:d9fd]:8333
[2602:ffea:a::c06:ae32]:8333
[2604:0:c1:100:1ec1:deff:fe54:2235]:8333
[2604:180:1:1af::42a9]:8333
[2604:180::b208:398]:8333
[2604:2880::6072:aed]:8333
[2604:4080:1114:0:3285:a9ff:fe93:850c]:8333
[2604:7c00:17:3d0::5a4d]:8333
[2604:9a00:2100:a009:2::]:8333
[2604:a880:1:20::22a:4001]:8333
[2604:a880:800:10::752:f001]:8333
[2604:c00:88:32:216:3eff:fee4:fcca]:8333
[2604:c00:88:32:216:3eff:fef5:bc21]:8333
[2605:7980:1:2::1761:3d4e]:8333
[2605:e000:1417:4068:223:32ff:fe96:e2d]:8333
[2606:6000:a441:9903:5054:ff:fe78:66ff]:8333
[2606:df00:2::ae85:8fc6]:8333
[2607:5300:100:200::e7f]:8333
[2607:5300:10::a1]:8333
[2607:5300:60:116e::1]:8333
[2607:5300:60:1535::]:8333
[2607:5300:60:1b32::1]:8333
[2607:5300:60:2337::1]:8333
[2607:5300:60:2b90::1]:8333
[2607:5300:60:2d99::1]:8333
[2607:5300:60:3cb::1]:8333
[2607:5300:60:4a85::]:8333
[2607:5300:60:5112:0:2:4af5:63fe]:8333
[2607:5300:60:6dd5::]:8333
[2607:5300:60:a91::1]:8333
[2607:f1c0:820:1500::7f:3f44]:8333
[2607:f1c0:848:1000::48:943c]:8333
[2607:f948:0:1::7]:8333
[2607:fcd0:100:2300::4ad:e594]:8333
[2607:fcd0:100:2300::659e:9cb3]:8333
[2607:fcd0:100:2300::c74b:a8ae]:8333
[2607:fcd0:100:2300::d82:d8c2]:8333
[2607:fcd0:100:4300::8795:2fa8]:8333
[2607:fcd0:daaa:901::9561:e043]:8333
[2a00:1178:2:43:5054:ff:fee7:2eb6]:8333
[2a00:1328:e100:cc42:230:48ff:fe92:55d]:8333
[2a00:14f0:e000:80d2:cd1a::1]:8333
[2a00:16d8:c::5b6a:c261]:8333
[2a00:61e0:4083:6d01:6852:1376:e972:2091]:8333
[2a00:c98:2030:a02f:2::2]:8333
[2a01:1b0:7999:402::131]:8333
[2a01:1e8:e100:811c:700f:65f0:f72a:1084]:8333
[2a01:238:42da:c500:6546:1293:5422:ab40]:8333
[2a01:348:6:473::2]:8333
[2a01:368:e010:2::2]:8333
[2a01:430:17:1::ffff:549]:8333
[2a01:430:17:1::ffff:830]:8333
[2a01:488:66:1000:53a9:d04:0:1]:8333
[2a01:488:66:1000:57e6:578c:0:1]:8333
[2a01:488:66:1000:b01c:178d:0:1]:8333
[2a01:488:67:1000:523:fdce:0:1]:8333
[2a01:488:67:1000:b01c:30ab:0:1]:8333
[2a01:4f8:100:24aa::2]:8333
[2a01:4f8:100:44e7::2]:8333
[2a01:4f8:100:5128::2]:8333
[2a01:4f8:100:84a7::1:1]:8333
[2a01:4f8:110:516c::2]:8333
[2a01:4f8:110:536e::2]:8333
[2a01:4f8:120:62e6::2]:8333
[2a01:4f8:120:702e::2]:8333
[2a01:4f8:120:8005::2]:8333
[2a01:4f8:120:8203::2]:8333
[2a01:4f8:120:8422::2]:8333
[2a01:4f8:121:11eb::2]:8333
[2a01:4f8:121:261::2]:8333
[2a01:4f8:130:242b::10]:8333
[2a01:4f8:130:242b::5]:8333
[2a01:4f8:130:2468::3]:8333
[2a01:4f8:130:632c::2]:8333
[2a01:4f8:130:6366::2]:8333
[2a01:4f8:130:6426::2]:8333
[2a01:4f8:130:934f::2]:8333
[2a01:4f8:131:2070::2]:8333
[2a01:4f8:131:54a2::2]:8333
[2a01:4f8:140:80ad::2]:8333
[2a01:4f8:141:186::2]:8333
[2a01:4f8:150:210b::2]:8333
[2a01:4f8:150:2263::5]:8333
[2a01:4f8:150:2349::2]:8333
[2a01:4f8:150:61ee::2]:8333
[2a01:4f8:150:7088:5054:ff:fe45:bff2]:8333
[2a01:4f8:150:8324::2]:9001
[2a01:4f8:151:1d8::2]:8333
[2a01:4f8:151:5128::2]:8333
[2a01:4f8:151:6347::2]:9001
[2a01:4f8:161:526d::2]:8333
[2a01:4f8:161:9349::2]:8333
[2a01:4f8:162:23c6::2]:8333
[2a01:4f8:162:4348::2]:8333
[2a01:4f8:162:7345::2]:8333
[2a01:4f8:162:7383::2]:8333
[2a01:4f8:162:74e3::2]:8333
[2a01:4f8:190:6065::2]:8333
[2a01:4f8:190:6349::2]:8333
[2a01:4f8:190:64c9::2]:8333
[2a01:4f8:190:91ce::2]:8333
[2a01:4f8:191:2194::83]:8333
[2a01:4f8:191:40a1::2]:8333
[2a01:4f8:191:4a7::2]:8333
[2a01:4f8:191:63b4:5000::1]:8333
[2a01:4f8:191:7121::2]:8333
[2a01:4f8:191:83a2::2]:8333
[2a01:4f8:191:93c4::2]:8333
[2a01:4f8:192:60a9:0:1:5:2]:8333
[2a01:4f8:192:73b2::2]:8333
[2a01:4f8:192:8098::2]:8333
[2a01:4f8:192:db::2]:8333
[2a01:4f8:200:1012::2]:8333
[2a01:4f8:200:22e3::2]:8333
[2a01:4f8:200:414e::2]:8333
[2a01:4f8:200:63af::222]:8333
[2a01:4f8:200:71e3:78b4:f3ff:fead:e8cf]:8333
[2a01:4f8:201:5164::2]:8333
[2a01:4f8:201:6011::4]:8333
[2a01:4f8:201:60d5::2]:8333
[2a01:4f8:202:53c3::2]:8333
[2a01:4f8:210:24aa::2]:8333
[2a01:4f8:210:502f::2]:8333
[2a01:4f8:211:14cf::2]:8333
[2a01:4f8:211:1a59::2]:8333
[2a01:4f8:211:2ac1::2]:8333
[2a01:4f8:211:cca::2]:8333
[2a01:4f8:a0:22a5::2]:8333
[2a01:4f8:a0:5023::2]:8333
[2a01:4f8:a0:5243::2]:8333
[2a01:4f8:a0:74c8::2]:8333
[2a01:4f8:a0:8227::2]:8333
[2a01:4f8:a0:822d::2]:8333
[2a01:4f8:d13:2183::2]:8333
[2a01:608:ffff:a009:8bf5:879d:e51a:f837]:8333
[2a01:79d:469e:ed94:c23f:d5ff:fe65:20c5]:8333
[2a01:7c8:aab5:3e6:5054:ff:fed7:4e54]:8333
[2a01:7e00::f03c:91ff:fe18:301e]:8333
[2a01:7e00::f03c:91ff:fe18:7749]:8333
[2a01:7e00::f03c:91ff:fe33:2d67]:8333
[2a01:7e00::f03c:91ff:fe33:347c]:8333
[2a01:7e00::f03c:91ff:fe33:ae50]:8333
[2a01:7e00::f03c:91ff:fe56:6b5c]:8333
[2a01:7e00::f03c:91ff:fe56:bee6]:8333
[2a01:7e00::f03c:91ff:fe69:4895]:8333
[2a01:7e00::f03c:91ff:fe69:9912]:8333
[2a01:7e00::f03c:91ff:fe6e:26ee]:8333
[2a01:7e00::f03c:91ff:fe73:42f1]:8333
[2a01:7e00::f03c:91ff:fe84:434f]:8333
[2a01:7e00::f03c:91ff:fe84:b36b]:8333
[2a01:7e00::f03c:91ff:fe89:1faa]:8333
[2a01:7e00::f03c:91ff:fe98:816]:8333
[2a01:7e00::f03c:91ff:fedb:352e]:8333
[2a01:7e00::f03c:91ff:fedb:4a1d]:8333
[2a01:e34:edbb:6750:224:1dff:fe89:3897]:8333
[2a01:e35:2f1d:3fb0:7187:c7ba:bcfc:80ce]:8333
[2a01:e35:8787:96f0:9032:9297:39ae:496d]:8333
[2a01:e35:8a3f:47c0:c617:feff:fe3c:9fbd]:8333
[2a01:e35:8b66:6a0:4900:9dfd:d841:d025]:8333
[2a02:168:4a01::39]:8333
[2a02:168:5404:2:c23f:d5ff:fe6a:512e]:8333
[2a02:180:1:1::5b8f:538c]:8333
[2a02:2028:1016::2]:8333
[2a02:2528:503:2::14]:8333
[2a02:2528:503:2::15]:8333
[2a02:2528:ff00:81a6:21e:c5ff:fe8d:f9a5]:8333
[2a02:2770:5:0:21a:4aff:fee4:c7db]:8333
[2a02:2770:8:0:21a:4aff:fe7b:3dcd]:8333
[2a02:348:5e:5a29::1]:8333
[2a02:7aa0:1619::202f:c06a]:8333
[2a02:8109:8e40:35fc:ba27:ebff:feae:cf16]:8333
[2a02:af8:6:1500::1:130]:8333
[2a02:c200:0:10:1:0:6314:2222]:8333
[2a02:c200:0:10:2:3:3295:1]:8332
[2a02:c200:0:10:3:0:5449:1]:8333
[2a02:c200:1:10:2:3:5899:1]:8333
[2a02:c200:1:10::2705:1]:8333
[2a02:ce80:0:20::1]:8333
[2a02:fe0:c321:27e0:6ef0:49ff:fe11:a61d]:8333
[2a03:4000:2:496::8]:8333
[2a03:b0c0:0:1010::62:f001]:8333
[2a03:f80:ed16:ca7:ea75:b12d:2af:9e2a]:8333
3ffk7iumtx3cegbi.onion:8333
3hshaantu6ot4upz.onion:8333
45c5lc77qgpikafy.onion:8333
77mx2jsxaoyesz2p.onion:8333
7g7j54btiaxhtsiy.onion:8333
b6fr7dlbu2kpiysf.onion:8333
bitcoincfqcssig5.onion:8333
bitcoinostk4e4re.onion:8333
bmutjfrj5btseddb.onion:8333
drp4pvejybx2ejdr.onion:8333
gixnv56d63buypan.onion:8333
h2vlpudzphzqxutd.onion:8333
hhiv5pnxenvbf4am.onion:8333
lzxpkn6ptp3ohh63.onion:8333
msphsgfiqfq5stne.onion:8333
ncwk3lutemffcpc4.onion:8333
okdzjarwekbshnof.onion:8333
sjdomi4yb2dwkjbc.onion:8333
uvwozwxlihntigbb.onion:8333
v6ylz45dn5ybpk4d.onion:8333
vk3qjdehyy4dwcxw.onion:8333
vqpye2k5rcqvj5mq.onion:8333
xudkoztdfrsuyyou.onion:8333
z55v4ostefnwfy32.onion:8333
185.25.48.236:27485
185.25.48.236:27487
185.64.105.111:27485
185.64.105.111:27487
185.25.48.72:27485
185.25.48.72:27487

View File

@@ -5,8 +5,8 @@
OSX_SDK_VERSION=10.9
OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
LD64_VERSION=241.9
! darwin_CC=gcc-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
! darwin_CXX=g++-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
! darwin_CC=gcc-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
! darwin_CXX=g++-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS)

View File

@@ -2,8 +2,8 @@
--- ../../komodo-jl777/depends/builders/darwin.mk 2017-01-03 09:48:21.646034937 +0000
***************
*** 1,5 ****
! build_darwin_CC = gcc-5
! build_darwin_CXX = g++-5
! build_darwin_CC = gcc-6
! build_darwin_CXX = g++-6
build_darwin_AR: = $(shell xcrun -f ar)
build_darwin_RANLIB: = $(shell xcrun -f ranlib)
build_darwin_STRIP: = $(shell xcrun -f strip)
@@ -21,8 +21,8 @@
! build_darwin_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O
#darwin host on darwin builder. overrides darwin host preferences.
! darwin_CC= gcc-5
! darwin_CXX= g++-5
! darwin_CC= gcc-6
! darwin_CXX= g++-6
darwin_AR:=$(shell xcrun -f ar)
darwin_RANLIB:=$(shell xcrun -f ranlib)
darwin_STRIP:=$(shell xcrun -f strip)

View File

@@ -1,5 +1,5 @@
build_darwin_CC = gcc-5
build_darwin_CXX = g++-5
build_darwin_CC = gcc-6
build_darwin_CXX = g++-6
build_darwin_AR: = $(shell xcrun -f ar)
build_darwin_RANLIB: = $(shell xcrun -f ranlib)
build_darwin_STRIP: = $(shell xcrun -f strip)
@@ -10,8 +10,8 @@ build_darwin_SHA256SUM = shasum -a 256
build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -f -o
#darwin host on darwin builder. overrides darwin host preferences.
darwin_CC= gcc-5
darwin_CXX= g++-5
darwin_CC= gcc-6
darwin_CXX= g++-6
darwin_AR:=$(shell xcrun -f ar)
darwin_RANLIB:=$(shell xcrun -f ranlib)
darwin_STRIP:=$(shell xcrun -f strip)

View File

@@ -2,8 +2,8 @@ OSX_MIN_VERSION=10.8
OSX_SDK_VERSION=10.11
OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
LD64_VERSION=253.9
darwin_CC=gcc-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
darwin_CXX=g++-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
darwin_CC=gcc-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
darwin_CXX=g++-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS)

View File

@@ -1,6 +1,6 @@
package=googletest
$(package)_version=1.8.0
$(package)_download_path=https://github.com/google/$(package)/archive/
$(package)_download_path=https://github.com/google/$(package)/archive
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_download_file=release-$($(package)_version).tar.gz
$(package)_sha256_hash=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8

View File

@@ -1,6 +1,6 @@
package=libevent
$(package)_version=2.1.8
$(package)_download_path=https://github.com/libevent/libevent/archive/
$(package)_download_path=https://github.com/libevent/libevent/archive
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_download_file=release-$($(package)_version)-stable.tar.gz
$(package)_sha256_hash=316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d

View File

@@ -1,7 +1,7 @@
package=libgmp
ifeq ($(host_os),mingw32)
$(package)_download_path=https://github.com/joshuayabut/$(package)/archive/
$(package)_download_path=https://github.com/joshuayabut/$(package)/archive
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
$(package)_download_file=$($(package)_git_commit).tar.gz
$(package)_sha256_hash=193836c1acc9dc00fe2521205d7bbe1ba13263f6cbef6f02584bf6f8b34b108f
@@ -9,7 +9,7 @@ $(package)_git_commit=053c03b1cab347671d936f43ef66b48ab5e380ee
$(package)_dependencies=
$(package)_config_opts=--enable-cxx --disable-shared
else ifeq ($(build_os),darwin)
$(package)_download_path=https://github.com/ca333/$(package)/archive/
$(package)_download_path=https://github.com/ca333/$(package)/archive
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
$(package)_download_file=$($(package)_git_commit).tar.gz
$(package)_sha256_hash=59b2c2b5d58fdf5943bfde1fa709e9eb53e7e072c9699d28dc1c2cbb3c8cc32c
@@ -18,7 +18,7 @@ $(package)_dependencies=
$(package)_config_opts=--enable-cxx --disable-shared
else
$(package)_version=6.1.1
$(package)_download_path=https://ftp.gnu.org/pub/gnu/gmp
$(package)_download_path=https://supernetorg.bintray.com/misc
$(package)_file_name=gmp-$($(package)_version).tar.bz2
$(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6
$(package)_dependencies=

View File

@@ -1,13 +1,12 @@
package=librustzcash
$(package)_version=0.1
$(package)_download_path=https://github.com/zcash/$(package)/archive/
$(package)_download_path=https://github.com/zcash/$(package)/archive
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
$(package)_download_file=$($(package)_git_commit).tar.gz
$(package)_sha256_hash=a5760a90d4a1045c8944204f29fa2a3cf2f800afee400f88bf89bbfe2cce1279
$(package)_git_commit=91348647a86201a9482ad4ad68398152dc3d635e
$(package)_dependencies=rust
ifeq ($(host_os),mingw32)
define $(package)_build_cmds
~/.cargo/bin/cargo build --release --target=x86_64-pc-windows-gnu --verbose

View File

@@ -14,15 +14,15 @@ define $(package)_set_vars
$(package)_build_env+=CXXFLAGS="$($(package)_cxxflags) -DBINARY_OUTPUT -DSTATICLIB -DNO_PT_COMPRESSION=1 "
endef
define $(package)_build_cmds
$(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64"
$(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64 -g "
endef
else ifeq ($(host_os),mingw32)
define $(package)_build_cmds
CXX="x86_64-w64-mingw32-g++-posix" CXXFLAGS="-DBINARY_OUTPUT -DPTW32_STATIC_LIB -DSTATICLIB -DNO_PT_COMPRESSION=1 -fopenmp" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64"
CXX="x86_64-w64-mingw32-g++-posix" CXXFLAGS="-DBINARY_OUTPUT -DPTW32_STATIC_LIB -DSTATICLIB -DNO_PT_COMPRESSION=1 -fopenmp" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64 -g "
endef
else
define $(package)_build_cmds
CXXFLAGS="-fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64"
CXXFLAGS="-fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64 -g "
endef
endif

View File

@@ -9,7 +9,7 @@ $(package)_config_opts=
else
package=libsodium
$(package)_version=1.0.15
$(package)_download_path=https://download.libsodium.org/libsodium/releases/
$(package)_download_path=https://download.libsodium.org/libsodium/releases
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4
$(package)_dependencies=

View File

@@ -1,6 +1,6 @@
ifeq ($(host_os),mingw32)
$(package)_version=4.2.2-1
$(package)_download_path=https://github.com/ca333/libzmq/archive/
$(package)_download_path=https://github.com/ca333/libzmq/archive
$(package)_download_file=v$($(package)_version).tar.gz
$(package)_file_name=libzmq-$($(package)_version).tar.gz
$(package)_sha256_hash=0e225b85ce11be23bf7eb7d3f25c6686728bf30d5c31f61c12d37bb646c69962
@@ -15,7 +15,7 @@ endef
else
package=zeromq
$(package)_version=4.2.1
$(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/
$(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=27d1e82a099228ee85a7ddb2260f40830212402c605a4a10b5e5498a7e0e9d03

View File

@@ -1,4 +1,5 @@
VerusCoin Command Line Tools v0.3.10-beta
VerusCoin Command Line Tools v0.3.13-beta
Contents:
komodod - VerusCoin's enhanced Komodo daemon
komodo-cli - VerusCoin's Komodo command line utility

View File

@@ -1,4 +1,4 @@
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
./komodod -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -addnode=185.25.48.236 -addnode=185.64.105.111 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -ac_veruspos=50 -gen -genproclimit=0 "$@"
./komodod -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -ac_veruspos=50 "$@"

View File

@@ -1,4 +1,4 @@
VerusCoin Command Line Tools v0.3.9-beta
VerusCoin Command Line Tools v0.3.13-beta
Contents:
komodod - VerusCoin's enhanced Komodo daemon.
komodo-cli - VerusCoin's enhanced Komodo command line utility.

View File

@@ -1,7 +1,199 @@
#!/bin/bash
set -eu
curl "https://z.cash/downloads/sprout-proving.key" -o "$HOME/Library/Application Support/ZcashParams/sprout-proving.key"
curl "https://z.cash/downloads/sprout-verifying.key" -o "$HOME/Library/Application Support/ZcashParams/sprout-verifying.key"
if [[ "$OSTYPE" == "darwin"* ]]; then
PARAMS_DIR="$HOME/Library/Application Support/ZcashParams"
else
PARAMS_DIR="$HOME/.zcash-params"
fi
SPROUT_PKEY_NAME='sprout-proving.key'
SPROUT_VKEY_NAME='sprout-verifying.key'
SAPLING_SPEND_NAME='sapling-spend.params'
SAPLING_OUTPUT_NAME='sapling-output.params'
SAPLING_SPROUT_GROTH16_NAME='sprout-groth16.params'
SPROUT_URL="https://z.cash/downloads"
SPROUT_IPFS="/ipfs/QmZKKx7Xup7LiAtFRhYsE1M7waXcv9ir9eCECyXAFGxhEo"
SHA256CMD="$(command -v sha256sum || echo shasum)"
SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')"
WGETCMD="$(command -v wget || echo '')"
IPFSCMD="$(command -v ipfs || echo '')"
CURLCMD="$(command -v curl || echo '')"
# fetch methods can be disabled with ZC_DISABLE_SOMETHING=1
ZC_DISABLE_WGET="${ZC_DISABLE_WGET:-}"
ZC_DISABLE_IPFS="${ZC_DISABLE_IPFS:-}"
ZC_DISABLE_CURL="${ZC_DISABLE_CURL:-}"
function fetch_wget {
if [ -z "$WGETCMD" ] || ! [ -z "$ZC_DISABLE_WGET" ]; then
return 1
fi
local filename="$1"
local dlname="$2"
cat <<EOF
Retrieving (wget): $SPROUT_URL/$filename
EOF
wget \
--progress=dot:giga \
--output-document="$dlname" \
--continue \
--retry-connrefused --waitretry=3 --timeout=30 \
"$SPROUT_URL/$filename"
}
function fetch_ipfs {
if [ -z "$IPFSCMD" ] || ! [ -z "$ZC_DISABLE_IPFS" ]; then
return 1
fi
local filename="$1"
local dlname="$2"
cat <<EOF
Retrieving (ipfs): $SPROUT_IPFS/$filename
EOF
ipfs get --output "$dlname" "$SPROUT_IPFS/$filename"
}
function fetch_curl {
if [ -z "$CURLCMD" ] || ! [ -z "$ZC_DISABLE_CURL" ]; then
return 1
fi
local filename="$1"
local dlname="$2"
cat <<EOF
Retrieving (curl): $SPROUT_URL/$filename
EOF
curl \
--output "$dlname" \
-# -L -C - \
"$SPROUT_URL/$filename"
}
function fetch_failure {
cat >&2 <<EOF
Failed to fetch the Zcash zkSNARK parameters!
Try installing one of the following programs and make sure you're online:
* ipfs
* wget
* curl
EOF
exit 1
}
function fetch_params {
local filename="$1"
local output="$2"
local dlname="${output}.dl"
local expectedhash="$3"
if ! [ -f "$output" ]
then
for method in wget ipfs curl failure; do
if "fetch_$method" "$filename" "$dlname"; then
echo "Download successful!"
break
fi
done
"$SHA256CMD" $SHA256ARGS -c <<EOF
$expectedhash $dlname
EOF
# Check the exit code of the shasum command:
CHECKSUM_RESULT=$?
if [ $CHECKSUM_RESULT -eq 0 ]; then
mv -v "$dlname" "$output"
else
echo "Failed to verify parameter checksums!" >&2
exit 1
fi
fi
}
# Use flock to prevent parallel execution.
function lock() {
local lockfile=/tmp/fetch_params.lock
if [[ "$OSTYPE" == "darwin"* ]]; then
if shlock -f ${lockfile} -p $$; then
return 0
else
return 1
fi
else
# create lock file
eval "exec 200>$lockfile"
# acquire the lock
flock -n 200 \
&& return 0 \
|| return 1
fi
}
function exit_locked_error {
echo "Only one instance of fetch-params.sh can be run at a time." >&2
exit 1
}
function main() {
lock fetch-params.sh \
|| exit_locked_error
cat <<EOF
Zcash - fetch-params.sh
This script will fetch the Zcash zkSNARK parameters and verify their
integrity with sha256sum.
If they already exist locally, it will exit now and do nothing else.
EOF
# Now create PARAMS_DIR and insert a README if necessary:
if ! [ -d "$PARAMS_DIR" ]
then
mkdir -p "$PARAMS_DIR"
README_PATH="$PARAMS_DIR/README"
cat >> "$README_PATH" <<EOF
This directory stores common Zcash zkSNARK parameters. Note that it is
distinct from the daemon's -datadir argument because the parameters are
large and may be shared across multiple distinct -datadir's such as when
setting up test networks.
EOF
# This may be the first time the user's run this script, so give
# them some info, especially about bandwidth usage:
cat <<EOF
The parameters are currently just under 911MB in size, so plan accordingly
for your bandwidth constraints. If the files are already present and
have the correct sha256sum, no networking is used.
Creating params directory. For details about this directory, see:
$README_PATH
EOF
fi
cd "$PARAMS_DIR"
# Sprout parameters:
fetch_params "$SPROUT_PKEY_NAME" "$PARAMS_DIR/$SPROUT_PKEY_NAME" "8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7"
fetch_params "$SPROUT_VKEY_NAME" "$PARAMS_DIR/$SPROUT_VKEY_NAME" "4bd498dae0aacfd8e98dc306338d017d9c08dd0918ead18172bd0aec2fc5df82"
# Sapling parameters:
fetch_params "$SAPLING_SPEND_NAME" "$PARAMS_DIR/$SAPLING_SPEND_NAME" "8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13"
fetch_params "$SAPLING_OUTPUT_NAME" "$PARAMS_DIR/$SAPLING_OUTPUT_NAME" "2f0ebbcbb9bb0bcffe95a397e7eba89c29eb4dde6191c339db88570e3f3fb0e4"
fetch_params "$SAPLING_SPROUT_GROTH16_NAME" "$PARAMS_DIR/$SAPLING_SPROUT_GROTH16_NAME" "b685d700c60328498fbde589c8c7c484c722b788b265b72af448a5bf0ee55b50"
}
main
rm -f /tmp/fetch_params.lock
exit 0

View File

@@ -3,4 +3,4 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
./komodod -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -addnode=185.25.48.236 -addnode=185.64.105.111 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -ac_veruspos=50 -gen -genproclimit=0 "$@"
./komodod -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -ac_veruspos=50 "$@"

View File

@@ -1,4 +1,4 @@
VerusCoin Command Line Tools v0.3.10-beta
VerusCoin Command Line Tools v0.3.13-beta
Contents:
komodod.exe - VerusCoin's enhanced Komodo daemon
komodo-cli.exe - VerusCoin's Komodo command line utility

View File

@@ -1,6 +1,6 @@
@call :GET_CURRENT_DIR
@cd %THIS_DIR%
komodod.exe -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -addnode=185.25.48.236 -addnode=185.64.105.111 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -ac_veruspos=50 -gen -genproclimit=0 %1 %2 %3 %4 %5 %6 %7 %8 %9
komodod.exe -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -ac_veruspos=50 %1 %2 %3 %4 %5 %6 %7 %8 %9
@goto :EOF
:GET_CURRENT_DIR

View File

@@ -4,7 +4,7 @@
*** 1,30 ****
package=libsnark
$(package)_version=0.1
! $(package)_download_path=https://github.com/radix42/$(package)/archive/
! $(package)_download_path=https://github.com/radix42/$(package)/archive
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
$(package)_download_file=$($(package)_git_commit).tar.gz
! $(package)_sha256_hash=9dbd5b44d3443e86463e934bfe1023cab4ca5948f8d74c23a67d9535c28d2584
@@ -14,11 +14,11 @@
- ifeq ($(build_os),darwin)
- define $(package)_build_cmds
- CC=gcc-5 CXX=g++-5 CXXFLAGS="-arch x86_64 -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=0 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT
- CC=gcc-6 CXX=g++-6 CXXFLAGS="-arch x86_64 -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=0 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT
- endef
- else
define $(package)_build_cmds
CXXFLAGS="-fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64"
CXXFLAGS="-fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64 -g "
endef
-
@@ -35,7 +35,7 @@
--- 1,17 ----
package=libsnark
$(package)_version=0.1
! $(package)_download_path=https://github.com/zcash/$(package)/archive/
! $(package)_download_path=https://github.com/zcash/$(package)/archive
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
$(package)_download_file=$($(package)_git_commit).tar.gz
! $(package)_sha256_hash=9422b1a2a94e6b8be61f07af7f146087c2a7d70b208d07ad076622225aa7f0e4
@@ -44,7 +44,7 @@
$(package)_dependencies=libgmp libsodium
define $(package)_build_cmds
CXXFLAGS="-fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64"
CXXFLAGS="-fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=1 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT OPTFLAGS="-O2 -march=x86-64 -g "
endef
define $(package)_stage_cmds

View File

@@ -1,3 +0,0 @@
#!/bin/sh
cp src/komodod.exe src/komodo-cli.exe src/komodo-tx.exe kmd/windows/verus-cli

61
migratecoin.md Normal file
View File

@@ -0,0 +1,61 @@
# MigrateCoin protocol
## ExportCoins tx:
```
vin:
[ any ]
vout:
- amount: {burnAmount}
script: OP_RETURN "send to ledger {id} {voutsHash}"
```
* ExportCoin is a standard tx which burns coins in an OP_RETURN
## ImportCoins tx:
```
vin:
- txid: 0000000000000000000000000000000000000000000000000000000000000000
idx: 0
script: CC_EVAL(EVAL_IMPORTCOINS, {momoProof},{exportCoin}) OP_CHECKCRYPTOCONDITION_UNILATERAL
vout:
- [ vouts matching voutsHash in exportCoin ]
```
* ImportCoin transaction has no signature
* ImportCoin is non malleable
* ImportCoin satisfies tx.IsCoinBase()
* ImportCoin uses a new opcode which allows a one sided check (no scriptPubKey)
* ImportCoin must contain CC opcode EVAL_IMPORTCOINS
* ImportCoin fees are equal to the difference between burnAmount in exportCoins and the sum of outputs.

View File

@@ -43,6 +43,7 @@ LIBBITCOIN_CLI=libbitcoin_cli.a
LIBBITCOIN_UTIL=libbitcoin_util.a
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
LIBVERUS_CRYPTO=crypto/libverus_crypto.a
LIBVERUS_PORTABLE_CRYPTO=crypto/libverus_portable_crypto.a
LIBSECP256K1=secp256k1/libsecp256k1.la
LIBCRYPTOCONDITIONS=cryptoconditions/libcryptoconditions_core.la
LIBSNARK=snark/libsnark.a
@@ -50,7 +51,7 @@ LIBUNIVALUE=univalue/libunivalue.la
LIBZCASH=libzcash.a -lcurl
$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g "
LIBSNARK_CXXFLAGS = -fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1 -fstack-protector-all
LIBSNARK_CONFIG_FLAGS = CURVE=ALT_BN128 NO_PROCPS=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT NO_COPY_DEPINST=1 NO_COMPILE_LIBGTEST=1
@@ -59,22 +60,23 @@ LIBSNARK_CONFIG_FLAGS += MULTICORE=1
endif
$(LIBSNARK): $(wildcard snark/src/*)
$(AM_V_at) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64"
$(AM_V_at) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64 -g "
libsnark-tests: $(wildcard snark/src/*)
$(AM_V_at) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ check DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64"
$(AM_V_at) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ check DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64 -g "
$(LIBUNIVALUE): $(wildcard univalue/lib/*)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue/
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue/ OPTFLAGS="-O2 -march=x86-64 -g "
$(LIBCRYPTOCONDITIONS): $(wildcard cryptoconditions/src/*) $(wildcard cryptoconditions/include/*)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g "
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
# But to build the less dependent modules first, we manually select their order here:
EXTRA_LIBRARIES = \
crypto/libbitcoin_crypto.a \
crypto/libverus_crypto.a \
crypto/libverus_portable_crypto.a \
libbitcoin_util.a \
libbitcoin_common.a \
libbitcoin_server.a \
@@ -263,11 +265,22 @@ libbitcoin_server_a_SOURCES = \
asyncrpcqueue.cpp \
bloom.cpp \
cc/eval.cpp \
cc/importpayout.cpp \
cc/disputepayout.cpp \
cc/import.cpp \
cc/CCassetsCore.cpp \
cc/CCcustom.cpp \
cc/CCtx.cpp \
cc/CCutils.cpp \
cc/assets.cpp \
cc/faucet.cpp \
cc/rewards.cpp \
cc/dice.cpp \
cc/lotto.cpp \
cc/ponzi.cpp \
cc/auction.cpp \
cc/betprotocol.cpp \
chain.cpp \
checkpoints.cpp \
crosschain.cpp \
crypto/haraka.h \
crypto/haraka_portable.h \
crypto/verus_hash.h \
@@ -283,12 +296,14 @@ libbitcoin_server_a_SOURCES = \
miner.cpp \
net.cpp \
noui.cpp \
notarisationdb.cpp \
paymentdisclosure.cpp \
paymentdisclosuredb.cpp \
policy/fees.cpp \
pow.cpp \
rest.cpp \
rpcblockchain.cpp \
rpccrosschain.cpp \
rpcmining.cpp \
rpcmisc.cpp \
rpcnet.cpp \
@@ -342,6 +357,8 @@ libbitcoin_wallet_a_SOURCES = \
paymentdisclosuredb.cpp \
wallet/rpcdisclosure.cpp \
wallet/rpcdump.cpp \
cc/CCassetstx.cpp \
cc/CCtx.cpp \
wallet/rpcwallet.cpp \
wallet/wallet.cpp \
wallet/wallet_ismine.cpp \
@@ -386,12 +403,17 @@ crypto_libbitcoin_crypto_a_SOURCES += \
${EQUIHASH_TROMP_SOURCES}
endif
# Verus hash specific library
crypto_libverus_crypto_a_CPPFLAGS = -O3 -Wint-conversion -march=native -funroll-loops -fomit-frame-pointer -fPIC $(AM_CPPFLAGS)
crypto_libverus_crypto_a_CXXFLAGS = -O3 -Wint-conversion -march=native -funroll-loops -fomit-frame-pointer -fPIC $(AM_CXXFLAGS)
# Verus hash specific library - optimized
crypto_libverus_crypto_a_CPPFLAGS = -O3 -Wint-conversion -march=x86-64 -msse4 -msse4.1 -msse4.2 -mssse3 -mavx -maes -g -funroll-loops -fomit-frame-pointer -fPIC $(AM_CPPFLAGS)
crypto_libverus_crypto_a_CXXFLAGS = -O3 -Wint-conversion -march=x86-64 -msse4 -msse4.1 -msse4.2 -mssse3 -mavx -maes -g -funroll-loops -fomit-frame-pointer -fPIC $(AM_CXXFLAGS)
crypto_libverus_crypto_a_SOURCES = \
crypto/haraka.h \
crypto/haraka.c \
crypto/haraka.c
# Verus hash specific library - portable
crypto_libverus_portable_crypto_a_CPPFLAGS = -O3 -Wint-conversion -march=x86-64 -g -funroll-loops -fomit-frame-pointer -fPIC $(AM_CPPFLAGS)
crypto_libverus_portable_crypto_a_CXXFLAGS = -O3 -Wint-conversion -march=x86-64 -g -funroll-loops -fomit-frame-pointer -fPIC $(AM_CXXFLAGS)
crypto_libverus_portable_crypto_a_SOURCES = \
crypto/haraka_portable.h \
crypto/haraka_portable.c
@@ -413,6 +435,7 @@ libbitcoin_common_a_SOURCES = \
crypto/verus_hash.h \
crypto/verus_hash.cpp \
hash.cpp \
importcoin.cpp \
key.cpp \
keystore.cpp \
netbase.cpp \
@@ -489,6 +512,7 @@ komodod_LDADD = \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
$(LIBVERUS_CRYPTO) \
$(LIBVERUS_PORTABLE_CRYPTO) \
$(LIBZCASH) \
$(LIBSNARK) \
$(LIBLEVELDB) \
@@ -513,6 +537,7 @@ komodod_LDADD += \
$(EVENT_LIBS) \
$(LIBBITCOIN_CRYPTO) \
$(LIBVERUS_CRYPTO) \
$(LIBVERUS_PORTABLE_CRYPTO) \
$(LIBZCASH_LIBS)
if ENABLE_PROTON
@@ -548,6 +573,7 @@ komodo_cli_LDADD = \
$(LIBZCASH) \
$(LIBBITCOIN_CRYPTO) \
$(LIBVERUS_CRYPTO) \
$(LIBVERUS_PORTABLE_CRYPTO) \
$(LIBZCASH_LIBS)
if ENABLE_WALLET
@@ -556,6 +582,7 @@ wallet_utility_LDADD = \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_CRYPTO) \
$(LIBVERUS_CRYPTO) \
$(LIBVERUS_PORTABLE_CRYPTO) \
$(LIBSECP256K1) \
$(LIBBITCOIN_UTIL) \
$(BOOST_LIBS) \
@@ -587,6 +614,7 @@ komodo_tx_LDADD = \
$(LIBSNARK) \
$(LIBBITCOIN_CRYPTO) \
$(LIBVERUS_CRYPTO) \
$(LIBVERUS_PORTABLE_CRYPTO) \
$(LIBZCASH_LIBS) \
$(LIBCRYPTOCONDITIONS)
@@ -642,7 +670,7 @@ endif
libzcashconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
libzcashconsensus_la_LIBADD = $(LIBSECP256K1)
libzcashconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL
libzcashconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -I$(srcdir)/cryptoconditions/include -DBUILD_BITCOIN_INTERNAL
libzcashconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
endif

View File

@@ -5,9 +5,13 @@ bin_PROGRAMS += komodo-test
# tool for generating our public parameters
komodo_test_SOURCES = \
test-komodo/main.cpp \
test-komodo/testutils.cpp \
test-komodo/test_cryptoconditions.cpp \
test-komodo/test_coinimport.cpp \
test-komodo/test_eval_bet.cpp \
test-komodo/test_eval_notarisation.cpp
test-komodo/test_eval_notarisation.cpp \
test-komodo/test_crosschain.cpp \
test-komodo/test_parse_notarisation.cpp
komodo_test_CPPFLAGS = $(komodod_CPPFLAGS)

View File

@@ -45,7 +45,6 @@ BITCOIN_TESTS =\
test/arith_uint256_tests.cpp \
test/bignum.h \
test/addrman_tests.cpp \
test/alert_tests.cpp \
test/allocator_tests.cpp \
test/base32_tests.cpp \
test/base58_tests.cpp \

2
src/ac/dsec Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=DSEC $1 $2 $3 $4 $5 $6

2
src/ac/eql Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=EQL $1 $2 $3 $4 $5 $6

2
src/ac/glxt Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=GLXT $1 $2 $3 $4 $5 $6

View File

@@ -7,7 +7,7 @@
#include "tinyformat.h"
const std::string CURRENCY_UNIT = "ZEC";
const std::string CURRENCY_UNIT = "KMD";
CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize)
{

View File

@@ -1,56 +1,19 @@
#!/bin/bash
set -eo pipefail
# You can now add delay line to pubkey.txt file
source pubkey.txt
args=("$@")
overide_args="$@"
seed_ip=`getent hosts zero.kolo.supernet.org | awk '{ print $1 }'`
komodo_binary='./komodod'
delay=20
function komodo_asset ()
{
if [ $[RANDOM % 10] == 1 ]
then
gen=" -gen"
else
gen=""
fi
if [ -z "$delay" ]; then delay=20; fi
if [ -n "$2" ]
then
supply=" -ac_supply=$2"
else
supply=" "
fi
./listassetchainparams | while read args; do
gen=""
if [ $[RANDOM % 10] == 1 ]; then
gen=" -gen"
fi
$komodo_binary -pubkey=$pubkey -ac_name=$1 $supply -addnode=$seed_ip $gen $args &
sleep $delay
}
#set -x
komodo_asset REVS 1300000
komodo_asset SUPERNET 816061
komodo_asset DEX 999999
komodo_asset PANGEA 999999
komodo_asset JUMBLR 999999
komodo_asset BET 999999
komodo_asset CRYPTO 999999
komodo_asset HODL 9999999
komodo_asset MSHARK 1400000
komodo_asset BOTS 999999
komodo_asset MGW 999999
komodo_asset COQUI 72000000
komodo_asset WLC 210000000
komodo_asset KV 1000000
komodo_asset CEAL 366666666
komodo_asset MESH 1000007
komodo_asset MNZ 257142858
komodo_asset AXO 200000000
komodo_asset ETOMIC 100000000
komodo_asset BTCH 20998641
komodo_asset PIZZA 100000000
komodo_asset BEER 100000000
komodo_asset NINJA 100000000
komodo_asset OOT 216000000
komodo_asset BNTN 500000000
komodo_asset CHAIN 999999
komodo_asset PRLPAY 500000000
./komodod $gen $args $overide_args -pubkey=$pubkey -addnode=$seed_ip &
sleep $delay
done

135
src/assetchains.json Normal file
View File

@@ -0,0 +1,135 @@
[
{
"ac_name": "REVS",
"ac_supply": "1300000"
},
{
"ac_name": "SUPERNET",
"ac_supply": "816061"
},
{
"ac_name": "DEX",
"ac_supply": "999999"
},
{
"ac_name": "PANGEA",
"ac_supply": "999999"
},
{
"ac_name": "JUMBLR",
"ac_supply": "999999"
},
{
"ac_name": "BET",
"ac_supply": "999999"
},
{
"ac_name": "CRYPTO",
"ac_supply": "999999"
},
{
"ac_name": "HODL",
"ac_supply": "9999999"
},
{
"ac_name": "MSHARK",
"ac_supply": "1400000"
},
{
"ac_name": "BOTS",
"ac_supply": "999999"
},
{
"ac_name": "MGW",
"ac_supply": "999999"
},
{
"ac_name": "COQUI",
"ac_supply": "72000000"
},
{
"ac_name": "WLC",
"ac_supply": "210000000"
},
{
"ac_name": "KV",
"ac_supply": "1000000"
},
{
"ac_name": "CEAL",
"ac_supply": "366666666"
},
{
"ac_name": "MESH",
"ac_supply": "1000007"
},
{
"ac_name": "MNZ",
"ac_supply": "257142858"
},
{
"ac_name": "AXO",
"ac_supply": "200000000"
},
{
"ac_name": "ETOMIC",
"ac_supply": "100000000"
},
{
"ac_name": "BTCH",
"ac_supply": "20998641"
},
{
"ac_name": "PIZZA",
"ac_supply": "100000000"
},
{
"ac_name": "BEER",
"ac_supply": "100000000"
},
{
"ac_name": "NINJA",
"ac_supply": "100000000"
},
{
"ac_name": "OOT",
"ac_supply": "216000000"
},
{
"ac_name": "BNTN",
"ac_supply": "500000000"
},
{
"ac_name": "CHAIN",
"ac_supply": "999999"
},
{
"ac_name": "PRLPAY",
"ac_supply": "500000000"
},
{
"ac_name": "DSEC",
"ac_supply": "7000000"
},
{
"ac_name": "GLXT",
"ac_supply": "10000000000"
},
{
"ac_name": "EQL",
"ac_supply": "500000000"
},
{
"ac_name": "ZILLA",
"ac_supply": "11000000"
},
{
"ac_name": "RFOX",
"ac_supply": "1000000000",
"ac_reward": "100000000"
},
{
"ac_name": "SEC",
"ac_supply": "1000000000"
}
]

View File

@@ -31,68 +31,10 @@ echo $pubkey
./komodod -pubkey=$pubkey -ac_name=BNTN -ac_supply=500000000 -addnode=94.130.169.205 &
./komodod -pubkey=$pubkey -ac_name=CHAIN -ac_supply=999999 -addnode=78.47.146.222 &
./komodod -pubkey=$pubkey -ac_name=PRLPAY -ac_supply=500000000 -addnode=13.250.226.125 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=USD -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=EUR -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=JPY -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=GBP -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=AUD -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=CAD -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=CHF -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=NZD -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=CNY -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=RUB -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=MXN -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=BRL -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=INR -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=HKD -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=TRY -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=ZAR -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=PLN -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=NOK -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=SEK -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=DKK -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=CZK -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=HUF -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=ILS -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=KRW -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=MYR -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=PHP -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=RON -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=SGD -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=THB -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=BGN -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=IDR -addnode=78.47.196.146 $1 &
#sleep $delay
#./komodod -pubkey=$pubkey -ac_name=HRK -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=DSEC -ac_supply=7000000 -addnode=185.148.147.30 &
./komodod -pubkey=$pubkey -ac_name=GLXT -ac_supply=10000000000 -addnode=13.230.224.15 &
./komodod -pubkey=$pubkey -ac_name=EQL -ac_supply=500000000 -addnode=46.101.124.153 &
./komodod -pubkey=$pubkey -ac_name=ZILLA -ac_supply=11000000 -addnode=54.39.23.248 &
./komodod -pubkey=$pubkey -ac_name=RFOX -ac_supply=1000000000 -ac_reward=100000000 -addnode=78.47.196.146 &
~/VerusCoin/src/komodod -pubkey=$pubkey -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_veruspos=50 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -addnode=185.25.48.236 -addnode=185.64.105.111 &
./komodod -pubkey=$pubkey -ac_name=SEC -ac_cc=333 -ac_supply=1000000000 -addnode=185.148.145.43 &

41
src/assetchains_stop Normal file → Executable file
View File

@@ -1,39 +1,6 @@
#!/bin/bash
args=("$@")
komodo_cli='./komodo-cli'
delay=20
set -eo pipefail
function komodo_stop ()
{
$komodo_cli --ac_name=$1 stop
}
#set -x
komodo_stop REVS
komodo_stop SUPERNET
komodo_stop DEX
komodo_stop PANGEA
komodo_stop JUMBLR
komodo_stop BET
komodo_stop CRYPTO
komodo_stop HODL
komodo_stop MSHARK
komodo_stop BOTS
komodo_stop MGW
komodo_stop COQUI
komodo_stop WLC
komodo_stop KV
komodo_stop CEAL
komodo_stop MESH
komodo_stop MNZ
komodo_stop AXO
komodo_stop ETOMIC
komodo_stop BTCH
komodo_stop PIZZA
komodo_stop BEER
komodo_stop NINJA
komodo_stop OOT
komodo_stop BNTN
komodo_stop CHAIN
komodo_stop PRLPAY
./listassetchains | while read chain; do
./komodo-cli --ac_name=$chain stop
done

View File

@@ -144,21 +144,21 @@ bool AppInit(int argc, char* argv[])
ReadConfigFile(mapArgs, mapMultiArgs);
} catch (const missing_zcash_conf& e) {
fprintf(stderr,
(_("Before starting zcashd, you need to create a configuration file:\n"
(_("Before starting komodod, you need to create a configuration file:\n"
"%s\n"
"It can be completely empty! That indicates you are happy with the default\n"
"configuration of zcashd. But requiring a configuration file to start ensures\n"
"that zcashd won't accidentally compromise your privacy if there was a default\n"
"configuration of komodod. But requiring a configuration file to start ensures\n"
"that komodod won't accidentally compromise your privacy if there was a default\n"
"option you needed to change.\n"
"\n"
"You can look at the example configuration file for suggestions of default\n"
"options that you may want to change. It should be in one of these locations,\n"
"depending on how you installed Zcash:\n") +
"depending on how you installed Komodo:\n") +
_("- Source code: %s\n"
"- .deb package: %s\n")).c_str(),
GetConfigFile().string().c_str(),
"contrib/debian/examples/zcash.conf",
"/usr/share/doc/zcash/examples/zcash.conf");
"contrib/debian/examples/komodo.conf",
"/usr/share/doc/komodo/examples/komodo.conf");
return false;
} catch (const std::exception& e) {
fprintf(stderr,"Error reading configuration file: %s\n", e.what());

65
src/cc/CCassets.h Normal file
View File

@@ -0,0 +1,65 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
/*
CCassetstx has the functions that create the EVAL_ASSETS transactions. It is expected that rpc calls would call these functions. For EVAL_ASSETS, the rpc functions are in rpcwallet.cpp
CCassetsCore has functions that are used in two contexts, both during rpc transaction create time and also during the blockchain validation. Using the identical functions is a good way to prevent them from being mismatched. The must match or the transaction will get rejected.
*/
#ifndef CC_ASSETS_H
#define CC_ASSETS_H
#include "CCinclude.h"
// CCcustom
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
// CCassetsCore
//CTxOut MakeAssetsVout(CAmount nValue,CPubKey pk);
CScript EncodeAssetCreateOpRet(uint8_t funcid,std::vector<uint8_t> origpubkey,std::string name,std::string description);
CScript EncodeAssetOpRet(uint8_t funcid,uint256 assetid,uint256 assetid2,int64_t price,std::vector<uint8_t> origpubkey);
bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t> &origpubkey,std::string &name,std::string &description);
uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector<uint8_t> &origpubkey);
bool SetAssetOrigpubkey(std::vector<uint8_t> &origpubkey,int64_t &price,const CTransaction &tx);
int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid);
bool ValidateBidRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
bool ValidateAskRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
bool SetBidFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice);
bool SetAskFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice);
bool SetSwapFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice);
int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid);
int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid);
bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid);
// CCassetstx
int64_t GetAssetBalance(CPubKey pk,uint256 tokenid);
int64_t AddAssetInputs(CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs);
UniValue AssetOrders(uint256 tokenid);
UniValue AssetInfo(uint256 tokenid);
UniValue AssetList();
std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description);
std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total);
std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal);
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid);
std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount);
std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal);
std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal);
std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid);
std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,int64_t fillamount);
#endif

478
src/cc/CCassetsCore.cpp Normal file
View File

@@ -0,0 +1,478 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCassets.h"
/*
The SetAssetFillamounts() and ValidateAssetRemainder() work in tandem to calculate the vouts for a fill and to validate the vouts, respectively.
This pair of functions are critical to make sure the trading is correct and is the trickiest part of the assets contract.
//vin.0: normal input
//vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0]
//vin.2+: valid CC output satisfies buyoffer (*tx.vin[2])->nValue
//vout.0: remaining amount of bid to unspendable
//vout.1: vin.1 value to signer of vin.2
//vout.2: vin.2 assetoshis to original pubkey
//vout.3: CC output for assetoshis change (if any)
//vout.4: normal output for change (if any)
//vout.n-1: opreturn [EVAL_ASSETS] ['B'] [assetid] [remaining asset required] [origpubkey]
ValidateAssetRemainder(remaining_price,tx.vout[0].nValue,nValue,tx.vout[1].nValue,tx.vout[2].nValue,totalunits);
Yes, this is quite confusing...
In ValudateAssetRemainder the naming convention is nValue is the coin/asset with the offer on the books and "units" is what it is being paid in. The high level check is to make sure we didnt lose any coins or assets, the harder to validate is the actual price paid as the "orderbook" is in terms of the combined nValue for the combined totalunits.
We assume that the effective unit cost in the orderbook is valid and that that amount was paid and also that any remainder will be close enough in effective unit cost to not matter. At the edge cases, this will probably be not true and maybe some orders wont be practically fillable when reduced to fractional state. However, the original pubkey that created the offer can always reclaim it.
*/
bool ValidateBidRemainder(int64_t remaining_units,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidunits,int64_t totalunits)
{
int64_t unitprice,recvunitprice,newunitprice=0;
if ( orig_nValue == 0 || received_nValue == 0 || paidunits == 0 || totalunits == 0 )
{
fprintf(stderr,"ValidateAssetRemainder: orig_nValue == %llu || received_nValue == %llu || paidunits == %llu || totalunits == %llu\n",(long long)orig_nValue,(long long)received_nValue,(long long)paidunits,(long long)totalunits);
return(false);
}
else if ( totalunits != (remaining_units + paidunits) )
{
fprintf(stderr,"ValidateAssetRemainder: totalunits %llu != %llu (remaining_units %llu + %llu paidunits)\n",(long long)totalunits,(long long)(remaining_units + paidunits),(long long)remaining_units,(long long)paidunits);
return(false);
}
else if ( orig_nValue != (remaining_nValue + received_nValue) )
{
fprintf(stderr,"ValidateAssetRemainder: orig_nValue %llu != %llu (remaining_nValue %llu + %llu received_nValue)\n",(long long)orig_nValue,(long long)(remaining_nValue - received_nValue),(long long)remaining_nValue,(long long)received_nValue);
return(false);
}
else
{
unitprice = (orig_nValue * COIN) / totalunits;
recvunitprice = (received_nValue * COIN) / paidunits;
if ( remaining_units != 0 )
newunitprice = (remaining_nValue * COIN) / remaining_units;
if ( recvunitprice < unitprice )
{
fprintf(stderr,"error recvunitprice %.16f < %.16f unitprice, new unitprice %.16f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN));
return(false);
}
fprintf(stderr,"orig %llu total %llu, recv %llu paid %llu,recvunitprice %.16f >= %.16f unitprice, new unitprice %.16f\n",(long long)orig_nValue,(long long)totalunits,(long long)received_nValue,(long long)paidunits,(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN));
}
return(true);
}
bool SetBidFillamounts(int64_t &received_nValue,int64_t &remaining_units,int64_t orig_nValue,int64_t &paidunits,int64_t totalunits)
{
int64_t remaining_nValue,unitprice; double dprice;
if ( totalunits == 0 )
{
received_nValue = remaining_units = paidunits = 0;
return(false);
}
if ( paidunits >= totalunits )
{
paidunits = totalunits;
received_nValue = orig_nValue;
remaining_units = 0;
fprintf(stderr,"totally filled!\n");
return(true);
}
remaining_units = (totalunits - paidunits);
unitprice = (orig_nValue * COIN) / totalunits;
received_nValue = (paidunits * unitprice) / COIN;
if ( unitprice > 0 && received_nValue > 0 && received_nValue <= orig_nValue )
{
remaining_nValue = (orig_nValue - received_nValue);
printf("total.%llu - paid.%llu, remaining %llu <- %llu (%llu - %llu)\n",(long long)totalunits,(long long)paidunits,(long long)remaining_nValue,(long long)(orig_nValue - received_nValue),(long long)orig_nValue,(long long)received_nValue);
return(ValidateBidRemainder(remaining_units,remaining_nValue,orig_nValue,received_nValue,paidunits,totalunits));
} else return(false);
}
bool SetAskFillamounts(int64_t &received_assetoshis,int64_t &remaining_nValue,int64_t orig_assetoshis,int64_t &paid_nValue,int64_t total_nValue)
{
int64_t remaining_assetoshis; double dunitprice;
if ( total_nValue == 0 )
{
received_assetoshis = remaining_nValue = paid_nValue = 0;
return(false);
}
if ( paid_nValue >= total_nValue )
{
paid_nValue = total_nValue;
received_assetoshis = orig_assetoshis;
remaining_nValue = 0;
fprintf(stderr,"totally filled!\n");
return(true);
}
remaining_nValue = (total_nValue - paid_nValue);
dunitprice = ((double)total_nValue / orig_assetoshis);
received_assetoshis = (paid_nValue / dunitprice);
fprintf(stderr,"remaining_nValue %.8f (%.8f - %.8f)\n",(double)remaining_nValue/COIN,(double)total_nValue/COIN,(double)paid_nValue/COIN);
fprintf(stderr,"unitprice %.8f received_assetoshis %llu orig %llu\n",dunitprice/COIN,(long long)received_assetoshis,(long long)orig_assetoshis);
if ( fabs(dunitprice) > SMALLVAL && received_assetoshis > 0 && received_assetoshis <= orig_assetoshis )
{
remaining_assetoshis = (orig_assetoshis - received_assetoshis);
return(ValidateAskRemainder(remaining_nValue,remaining_assetoshis,orig_assetoshis,received_assetoshis,paid_nValue,total_nValue));
} else return(false);
}
bool ValidateAskRemainder(int64_t remaining_nValue,int64_t remaining_assetoshis,int64_t orig_assetoshis,int64_t received_assetoshis,int64_t paid_nValue,int64_t total_nValue)
{
int64_t unitprice,recvunitprice,newunitprice=0;
if ( orig_assetoshis == 0 || received_assetoshis == 0 || paid_nValue == 0 || total_nValue == 0 )
{
fprintf(stderr,"ValidateAssetRemainder: orig_assetoshis == %llu || received_assetoshis == %llu || paid_nValue == %llu || total_nValue == %llu\n",(long long)orig_assetoshis,(long long)received_assetoshis,(long long)paid_nValue,(long long)total_nValue);
return(false);
}
else if ( total_nValue != (remaining_nValue + paid_nValue) )
{
fprintf(stderr,"ValidateAssetRemainder: total_nValue %llu != %llu (remaining_nValue %llu + %llu paid_nValue)\n",(long long)total_nValue,(long long)(remaining_nValue + paid_nValue),(long long)remaining_nValue,(long long)paid_nValue);
return(false);
}
else if ( orig_assetoshis != (remaining_assetoshis + received_assetoshis) )
{
fprintf(stderr,"ValidateAssetRemainder: orig_assetoshis %llu != %llu (remaining_nValue %llu + %llu received_nValue)\n",(long long)orig_assetoshis,(long long)(remaining_assetoshis - received_assetoshis),(long long)remaining_assetoshis,(long long)received_assetoshis);
return(false);
}
else
{
unitprice = (total_nValue / orig_assetoshis);
recvunitprice = (paid_nValue / received_assetoshis);
if ( remaining_nValue != 0 )
newunitprice = (remaining_nValue / remaining_assetoshis);
if ( recvunitprice < unitprice )
{
fprintf(stderr,"error recvunitprice %.8f < %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/COIN,(double)unitprice/COIN,(double)newunitprice/COIN);
return(false);
}
fprintf(stderr,"got recvunitprice %.8f >= %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/COIN,(double)unitprice/COIN,(double)newunitprice/COIN);
}
return(true);
}
bool SetSwapFillamounts(int64_t &received_assetoshis,int64_t &remaining_assetoshis2,int64_t orig_assetoshis,int64_t &paid_assetoshis2,int64_t total_assetoshis2)
{
int64_t remaining_assetoshis; double dunitprice;
if ( total_assetoshis2 == 0 )
{
fprintf(stderr,"total_assetoshis2.0 origsatoshis.%llu paid_assetoshis2.%llu\n",(long long)orig_assetoshis,(long long)paid_assetoshis2);
received_assetoshis = remaining_assetoshis2 = paid_assetoshis2 = 0;
return(false);
}
if ( paid_assetoshis2 >= total_assetoshis2 )
{
paid_assetoshis2 = total_assetoshis2;
received_assetoshis = orig_assetoshis;
remaining_assetoshis2 = 0;
fprintf(stderr,"totally filled!\n");
return(true);
}
remaining_assetoshis2 = (total_assetoshis2 - paid_assetoshis2);
dunitprice = ((double)total_assetoshis2 / orig_assetoshis);
received_assetoshis = (paid_assetoshis2 / dunitprice);
fprintf(stderr,"remaining_assetoshis2 %llu (%llu - %llu)\n",(long long)remaining_assetoshis2/COIN,(long long)total_assetoshis2/COIN,(long long)paid_assetoshis2/COIN);
fprintf(stderr,"unitprice %.8f received_assetoshis %llu orig %llu\n",dunitprice/COIN,(long long)received_assetoshis,(long long)orig_assetoshis);
if ( fabs(dunitprice) > SMALLVAL && received_assetoshis > 0 && received_assetoshis <= orig_assetoshis )
{
remaining_assetoshis = (orig_assetoshis - received_assetoshis);
return(ValidateAskRemainder(remaining_assetoshis2,remaining_assetoshis,orig_assetoshis,received_assetoshis,paid_assetoshis2,total_assetoshis2));
} else return(false);
}
bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidunits,int64_t totalunits)
{
int64_t unitprice,recvunitprice,newunitprice=0;
if ( orig_nValue == 0 || received_nValue == 0 || paidunits == 0 || totalunits == 0 )
{
fprintf(stderr,"ValidateAssetRemainder: orig_nValue == %llu || received_nValue == %llu || paidunits == %llu || totalunits == %llu\n",(long long)orig_nValue,(long long)received_nValue,(long long)paidunits,(long long)totalunits);
return(false);
}
else if ( totalunits != (remaining_price + paidunits) )
{
fprintf(stderr,"ValidateAssetRemainder: totalunits %llu != %llu (remaining_price %llu + %llu paidunits)\n",(long long)totalunits,(long long)(remaining_price + paidunits),(long long)remaining_price,(long long)paidunits);
return(false);
}
else if ( orig_nValue != (remaining_nValue + received_nValue) )
{
fprintf(stderr,"ValidateAssetRemainder: orig_nValue %llu != %llu (remaining_nValue %llu + %llu received_nValue)\n",(long long)orig_nValue,(long long)(remaining_nValue - received_nValue),(long long)remaining_nValue,(long long)received_nValue);
return(false);
}
else
{
unitprice = (orig_nValue * COIN) / totalunits;
recvunitprice = (received_nValue * COIN) / paidunits;
if ( remaining_price != 0 )
newunitprice = (remaining_nValue * COIN) / remaining_price;
if ( recvunitprice < unitprice )
{
fprintf(stderr,"error recvunitprice %.16f < %.16f unitprice, new unitprice %.16f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN));
return(false);
}
fprintf(stderr,"recvunitprice %.16f >= %.16f unitprice, new unitprice %.16f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN));
}
return(true);
}
CScript EncodeAssetCreateOpRet(uint8_t funcid,std::vector<uint8_t> origpubkey,std::string name,std::string description)
{
CScript opret; uint8_t evalcode = EVAL_ASSETS;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << origpubkey << name << description);
return(opret);
}
CScript EncodeAssetOpRet(uint8_t funcid,uint256 assetid,uint256 assetid2,int64_t price,std::vector<uint8_t> origpubkey)
{
CScript opret; uint8_t evalcode = EVAL_ASSETS;
assetid = revuint256(assetid);
switch ( funcid )
{
case 't': case 'x': case 'o':
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << assetid);
break;
case 's': case 'b': case 'S': case 'B':
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << assetid << price << origpubkey);
break;
case 'E': case 'e':
assetid2 = revuint256(assetid2);
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << assetid << assetid2 << price << origpubkey);
break;
default:
fprintf(stderr,"EncodeOpRet: illegal funcid.%02x\n",funcid);
opret << OP_RETURN;
break;
}
return(opret);
}
bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t> &origpubkey,std::string &name,std::string &description)
{
std::vector<uint8_t> vopret; uint8_t evalcode,funcid,*script;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( script != 0 && vopret.size() > 2 && script[0] == EVAL_ASSETS && script[1] == 'c' )
{
if ( E_UNMARSHAL(vopret,ss >> evalcode; ss >> funcid; ss >> origpubkey; ss >> name; ss >> description) != 0 )
return(true);
}
return(0);
}
uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector<uint8_t> &origpubkey)
{
std::vector<uint8_t> vopret; uint8_t funcid=0,*script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
memset(&assetid,0,sizeof(assetid));
memset(&assetid2,0,sizeof(assetid2));
price = 0;
if ( script != 0 && script[0] == EVAL_ASSETS )
{
funcid = script[1];
//fprintf(stderr,"decode.[%c]\n",funcid);
switch ( funcid )
{
case 'c': return(funcid);
break;
case 't': case 'x': case 'o':
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid) != 0 )
{
assetid = revuint256(assetid);
return(funcid);
}
break;
case 's': case 'b': case 'S': case 'B':
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> price; ss >> origpubkey) != 0 )
{
assetid = revuint256(assetid);
//fprintf(stderr,"got price %llu\n",(long long)price);
return(funcid);
}
break;
case 'E': case 'e':
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> assetid2; ss >> price; ss >> origpubkey) != 0 )
{
//fprintf(stderr,"got price %llu\n",(long long)price);
assetid = revuint256(assetid);
assetid2 = revuint256(assetid2);
return(funcid);
}
break;
default:
fprintf(stderr,"DecodeAssetOpRet: illegal funcid.%02x\n",funcid);
funcid = 0;
break;
}
}
return(funcid);
}
bool SetAssetOrigpubkey(std::vector<uint8_t> &origpubkey,int64_t &price,const CTransaction &tx)
{
uint256 assetid,assetid2;
if ( tx.vout.size() > 0 && DecodeAssetOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,assetid,assetid2,price,origpubkey) != 0 )
return(true);
else return(false);
}
bool GetAssetorigaddrs(struct CCcontract_info *cp,char *CCaddr,char *destaddr,const CTransaction& tx)
{
uint256 assetid,assetid2; int64_t price,nValue=0; int32_t n; uint8_t funcid; std::vector<uint8_t> origpubkey; CScript script;
n = tx.vout.size();
if ( n == 0 || (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 )
return(false);
if ( GetCCaddress(cp,CCaddr,pubkey2pk(origpubkey)) != 0 && Getscriptaddress(destaddr,CScript() << origpubkey << OP_CHECKSIG) != 0 )
return(true);
else return(false);
}
int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid)
{
uint256 assetid,assetid2; int64_t nValue=0; int32_t n; uint8_t funcid;
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) // maybe check address too?
{
n = tx.vout.size();
nValue = tx.vout[v].nValue;
//fprintf(stderr,"CC vout v.%d of n.%d %.8f\n",v,n,(double)nValue/COIN);
if ( v >= n-1 )
return(0);
if ( (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 )
{
fprintf(stderr,"null decodeopret\n");
return(0);
}
else if ( funcid == 'c' )
{
if ( refassetid == tx.GetHash() && v == 0 )
return(nValue);
}
else if ( (funcid == 'b' || funcid == 'B') && v == 0 ) // critical! 'b'/'B' vout0 is NOT asset
return(0);
else if ( funcid != 'E' )
{
if ( assetid == refassetid )
return(nValue);
}
else if ( funcid == 'E' )
{
if ( v < 2 && assetid == refassetid )
return(nValue);
else if ( v == 2 && assetid2 == refassetid )
return(nValue);
}
}
//fprintf(stderr,"Isassetvout: normal output v.%d %.8f\n",v,(double)tx.vout[v].nValue/COIN);
return(0);
}
int64_t AssetValidateCCvin(struct CCcontract_info *cp,Eval* eval,char *CCaddr,char *origaddr,const CTransaction &tx,int32_t vini,CTransaction &vinTx)
{
uint256 hashBlock; char destaddr[64];
origaddr[0] = destaddr[0] = CCaddr[0] = 0;
if ( tx.vin.size() < 2 )
return eval->Invalid("not enough for CC vins");
else if ( tx.vin[vini].prevout.n != 0 )
return eval->Invalid("vin1 needs to be buyvin.vout[0]");
else if ( eval->GetTxUnconfirmed(tx.vin[vini].prevout.hash,vinTx,hashBlock) == 0 )
{
int32_t z;
for (z=31; z>=0; z--)
fprintf(stderr,"%02x",((uint8_t *)&tx.vin[vini].prevout.hash)[z]);
fprintf(stderr," vini.%d\n",vini);
return eval->Invalid("always should find CCvin, but didnt");
}
else if ( Getscriptaddress(destaddr,vinTx.vout[tx.vin[vini].prevout.n].scriptPubKey) == 0 || strcmp(destaddr,(char *)cp->unspendableCCaddr) != 0 )
{
fprintf(stderr,"%s vs %s\n",destaddr,(char *)cp->unspendableCCaddr);
return eval->Invalid("invalid vin AssetsCCaddr");
}
//else if ( vinTx.vout[0].nValue < 10000 )
// return eval->Invalid("invalid dust for buyvin");
else if ( GetAssetorigaddrs(cp,CCaddr,origaddr,vinTx) == 0 )
return eval->Invalid("couldnt get origaddr for buyvin");
fprintf(stderr,"Got %.8f to origaddr.(%s)\n",(double)vinTx.vout[tx.vin[vini].prevout.n].nValue/COIN,origaddr);
if ( vinTx.vout[0].nValue == 0 )
return eval->Invalid("null value CCvin");
return(vinTx.vout[0].nValue);
}
int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid)
{
CTransaction vinTx; int64_t nValue; uint256 assetid,assetid2; uint8_t funcid;
CCaddr[0] = origaddr[0] = 0;
if ( (nValue= AssetValidateCCvin(cp,eval,CCaddr,origaddr,tx,1,vinTx)) == 0 )
return(0);
else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
return eval->Invalid("invalid normal vout0 for buyvin");
else
{
//fprintf(stderr,"have %.8f checking assetid origaddr.(%s)\n",(double)nValue/COIN,origaddr);
if ( vinTx.vout.size() > 0 && (funcid= DecodeAssetOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,assetid,assetid2,tmpprice,tmporigpubkey)) != 'b' && funcid != 'B' )
return eval->Invalid("invalid opreturn for buyvin");
else if ( refassetid != assetid )
return eval->Invalid("invalid assetid for buyvin");
//int32_t i; for (i=31; i>=0; i--)
// fprintf(stderr,"%02x",((uint8_t *)&assetid)[i]);
//fprintf(stderr," AssetValidateBuyvin assetid for %s\n",origaddr);
}
return(nValue);
}
int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid)
{
CTransaction vinTx; int64_t nValue,assetoshis;
fprintf(stderr,"AssetValidateSellvin\n");
if ( (nValue= AssetValidateCCvin(cp,eval,CCaddr,origaddr,tx,1,vinTx)) == 0 )
return(0);
if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,0,assetid)) == 0 )
return eval->Invalid("invalid missing CC vout0 for sellvin");
else return(assetoshis);
}
bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid)
{
CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; int64_t assetoshis; std::vector<uint8_t> tmporigpubkey; int64_t tmpprice;
numvins = tx.vin.size();
numvouts = tx.vout.size();
inputs = outputs = 0;
for (i=starti; i<numvins; i++)
{
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
{
fprintf(stderr,"i.%d starti.%d numvins.%d\n",i,starti,numvins);
return eval->Invalid("always should find vin, but didnt");
}
else if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,tx.vin[i].prevout.n,assetid)) != 0 )
{
fprintf(stderr,"vin%d %llu, ",i,(long long)assetoshis);
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,tx,i,assetid)) != 0 )
{
fprintf(stderr,"vout%d %llu, ",i,(long long)assetoshis);
outputs += assetoshis;
}
}
if ( inputs != outputs )
{
fprintf(stderr,"inputs %.8f vs %.8f outputs\n",(double)inputs/COIN,(double)outputs/COIN);
return(false);
}
else return(true);
}

472
src/cc/CCassetstx.cpp Normal file
View File

@@ -0,0 +1,472 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCassets.h"
// need allassets
// find asset
int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs)
{
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;
if ( j != mtx.vin.size() )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsAssetvout(price,origpubkey,vintx,vout,assetid)) > 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
}
}
}
return(totalinputs);
}
int64_t GetAssetBalance(CPubKey pk,uint256 tokenid)
{
CMutableTransaction mtx; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_ASSETS);
return(AddAssetInputs(cp,mtx,pk,tokenid,0,0));
}
UniValue AssetInfo(uint256 assetid)
{
UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description; char str[67],numstr[65];
if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find assetid\n");
result.push_back(Pair("error","cant find assetid"));
return(0);
}
if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) == 0 )
{
fprintf(stderr,"assetid isnt assetcreation txid\n");
result.push_back(Pair("error","assetid isnt assetcreation txid"));
}
result.push_back(Pair("result","success"));
result.push_back(Pair("tokenid",uint256_str(str,assetid)));
result.push_back(Pair("owner",pubkey33_str(str,origpubkey.data())));
result.push_back(Pair("name",name));
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN);
result.push_back(Pair("supply",numstr));
result.push_back(Pair("description",description));
return(result);
}
UniValue AssetList()
{
UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description; char str[65];
cp = CCinit(&C,EVAL_ASSETS);
SetCCtxids(addressIndex,cp->normaladdr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) != 0 )
{
result.push_back(uint256_str(str,txid));
}
}
}
return(result);
}
UniValue AssetOrders(uint256 refassetid)
{
static uint256 zero;
int64_t price; uint256 txid,hashBlock,assetid,assetid2; std::vector<uint8_t> origpubkey; CTransaction vintx; UniValue result(UniValue::VARR); std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; uint8_t funcid; char numstr[32],funcidstr[16],origaddr[64],assetidstr[65]; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_ASSETS);
SetCCunspents(unspentOutputs,(char *)cp->unspendableCCaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( vintx.vout.size() > 0 && (funcid= DecodeAssetOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,assetid,assetid2,price,origpubkey)) != 0 )
{
if ( refassetid != zero && assetid != refassetid )
{
//int32_t z;
//for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&txid)[z]);
//fprintf(stderr," txid\n");
//for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&assetid)[z]);
//fprintf(stderr," assetid\n");
//for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&refassetid)[z]);
//fprintf(stderr," refassetid\n");
continue;
}
if ( vintx.vout[it->first.index].nValue == 0 )
continue;
UniValue item(UniValue::VOBJ);
funcidstr[0] = funcid;
funcidstr[1] = 0;
item.push_back(Pair("funcid", funcidstr));
item.push_back(Pair("txid", uint256_str(assetidstr,txid)));
item.push_back(Pair("vout", (int64_t)it->first.index));
if ( funcid == 'b' || funcid == 'B' )
{
sprintf(numstr,"%.8f",(double)vintx.vout[it->first.index].nValue/COIN);
item.push_back(Pair("amount",numstr));
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN);
item.push_back(Pair("bidamount",numstr));
}
else
{
sprintf(numstr,"%llu",(long long)vintx.vout[it->first.index].nValue);
item.push_back(Pair("amount",numstr));
sprintf(numstr,"%llu",(long long)vintx.vout[0].nValue);
item.push_back(Pair("askamount",numstr));
}
if ( origpubkey.size() == 33 )
{
GetCCaddress(cp,origaddr,pubkey2pk(origpubkey));
item.push_back(Pair("origaddress",origaddr));
}
if ( assetid != zeroid )
item.push_back(Pair("tokenid",uint256_str(assetidstr,assetid)));
if ( assetid2 != zeroid )
item.push_back(Pair("otherid",uint256_str(assetidstr,assetid2)));
if ( price > 0 )
{
if ( funcid == 's' || funcid == 'S' || funcid == 'e' || funcid == 'e' )
{
sprintf(numstr,"%.8f",(double)price / COIN);
item.push_back(Pair("totalrequired", numstr));
sprintf(numstr,"%.8f",(double)price / (COIN * vintx.vout[0].nValue));
item.push_back(Pair("price", numstr));
}
else
{
item.push_back(Pair("totalrequired", (int64_t)price));
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue / (price * COIN));
item.push_back(Pair("price",numstr));
}
}
result.push_back(item);
//fprintf(stderr,"func.(%c) %s/v%d %.8f\n",funcid,uint256_str(assetidstr,txid),(int32_t)it->first.index,(double)vintx.vout[it->first.index].nValue/COIN);
}
}
}
return(result);
}
std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description)
{
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C;
if ( assetsupply < 0 )
{
fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply);
return(0);
}
cp = CCinit(&C,EVAL_ASSETS);
if ( name.size() > 32 || description.size() > 4096 )
{
fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size());
return(0);
}
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,assetsupply+2*txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,assetsupply,mypk));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(cp->CChexstr) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetCreateOpRet('c',Mypubkey(),name,description)));
}
return(0);
}
std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total)
{
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
if ( total < 0 )
{
fprintf(stderr,"negative total %lld\n",(long long)total);
return(0);
}
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
/*n = outputs.size();
if ( n == amounts.size() )
{
for (i=0; i<n; i++)
total += amounts[i];*/
mask = ~((1LL << mtx.vin.size()) - 1);
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 )
{
if ( inputs > total )
CCchange = (inputs - total);
//for (i=0; i<n; i++)
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,total,pubkey2pk(destpubkey)));
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
} else fprintf(stderr,"not enough CC asset inputs for %.8f\n",(double)total/COIN);
//} else fprintf(stderr,"numoutputs.%d != numamounts.%d\n",n,(int32_t)amounts.size());
}
return(0);
}
std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal)
{
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description;
if ( bidamount < 0 || pricetotal < 0 )
{
fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n",(long long)bidamount,(long long)pricetotal);
return(0);
}
if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find assetid\n");
return(0);
}
if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) == 0 )
{
fprintf(stderr,"assetid isnt assetcreation txid\n");
return(0);
}
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,bidamount+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,bidamount,GetUnspendable(cp,0)));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('b',assetid,zeroid,pricetotal,Mypubkey())));
}
return(0);
}
std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal)
{
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
if ( askamount < 0 || pricetotal < 0 )
{
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
return(0);
}
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
mask = ~((1LL << mtx.vin.size()) - 1);
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
{
if ( inputs < askamount )
askamount = inputs;
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,GetUnspendable(cp,0)));
if ( inputs > askamount )
CCchange = (inputs - askamount);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
opret = EncodeAssetOpRet('s',assetid,zeroid,pricetotal,Mypubkey());
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
} else fprintf(stderr,"need some assets to place ask\n");
}
fprintf(stderr,"need some native coins to place ask\n");
return(0);
}
std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal)
{
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
if ( askamount < 0 || pricetotal < 0 )
{
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
return(0);
}
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
mask = ~((1LL << mtx.vin.size()) - 1);
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
{
if ( inputs < askamount )
askamount = inputs;
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,GetUnspendable(cp,0)));
if ( inputs > askamount )
CCchange = (inputs - askamount);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
if ( assetid2 == zeroid )
opret = EncodeAssetOpRet('s',assetid,zeroid,pricetotal,Mypubkey());
else
{
opret = EncodeAssetOpRet('e',assetid,assetid2,pricetotal,Mypubkey());
}
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
} else fprintf(stderr,"need some assets to place ask\n");
}
fprintf(stderr,"need some native coins to place ask\n");
return(0);
}
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
{
CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
mask = ~((1LL << mtx.vin.size()) - 1);
if ( GetTransaction(bidtxid,vintx,hashBlock,false) != 0 )
{
bidamount = vintx.vout[0].nValue;
mtx.vin.push_back(CTxIn(bidtxid,0,CScript()));
mtx.vout.push_back(CTxOut(bidamount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('o',assetid,zeroid,0,Mypubkey())));
}
}
return(0);
}
std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
{
CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
mask = ~((1LL << mtx.vin.size()) - 1);
if ( GetTransaction(asktxid,vintx,hashBlock,false) != 0 )
{
askamount = vintx.vout[0].nValue;
mtx.vin.push_back(CTxIn(asktxid,0,CScript()));
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,mypk));
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('x',assetid,zeroid,0,Mypubkey())));
}
}
return(0);
}
std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount)
{
CTransaction vintx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; int32_t bidvout=0; uint64_t mask; int64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C;
if ( fillamount < 0 )
{
fprintf(stderr,"negative fillamount %lld\n",(long long)fillamount);
return(0);
}
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
mask = ~((1LL << mtx.vin.size()) - 1);
if ( GetTransaction(bidtxid,vintx,hashBlock,false) != 0 )
{
bidamount = vintx.vout[bidvout].nValue;
SetAssetOrigpubkey(origpubkey,origprice,vintx);
mtx.vin.push_back(CTxIn(bidtxid,bidvout,CScript()));
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,fillamount,60)) > 0 )
{
if ( inputs < fillamount )
fillamount = inputs;
SetBidFillamounts(paid_amount,remaining_required,bidamount,fillamount,origprice);
if ( inputs > fillamount )
CCchange = (inputs - fillamount);
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,bidamount - paid_amount,GetUnspendable(cp,0)));
mtx.vout.push_back(CTxOut(paid_amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,fillamount,pubkey2pk(origpubkey)));
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
fprintf(stderr,"remaining %llu -> origpubkey\n",(long long)remaining_required);
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('B',assetid,zeroid,remaining_required,origpubkey)));
} else return("dont have any assets to fill bid\n");
}
}
return("no normal coins left");
}
std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,int64_t fillunits)
{
CTransaction vintx,filltx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C;
if ( fillunits < 0 )
{
fprintf(stderr,"negative fillunits %lld\n",(long long)fillunits);
return(0);
}
cp = CCinit(&C,EVAL_ASSETS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
mask = ~((1LL << mtx.vin.size()) - 1);
if ( GetTransaction(asktxid,vintx,hashBlock,false) != 0 )
{
orig_assetoshis = vintx.vout[askvout].nValue;
SetAssetOrigpubkey(origpubkey,total_nValue,vintx);
dprice = (double)total_nValue / orig_assetoshis;
paid_nValue = dprice * fillunits;
mtx.vin.push_back(CTxIn(asktxid,askvout,CScript()));
if ( assetid2 != zeroid )
inputs = AddAssetInputs(cp,mtx,mypk,assetid2,paid_nValue,60);
else
{
inputs = AddNormalinputs(mtx,mypk,paid_nValue,60);
mask = ~((1LL << mtx.vin.size()) - 1);
}
if ( inputs > 0 )
{
if ( inputs < paid_nValue )
paid_nValue = inputs;
if ( assetid2 != zeroid )
SetSwapFillamounts(received_assetoshis,remaining_nValue,orig_assetoshis,paid_nValue,total_nValue);
else SetAskFillamounts(received_assetoshis,remaining_nValue,orig_assetoshis,paid_nValue,total_nValue);
if ( assetid2 != zeroid && inputs > paid_nValue )
CCchange = (inputs - paid_nValue);
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,orig_assetoshis - received_assetoshis,GetUnspendable(cp,0)));
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,received_assetoshis,mypk));
mtx.vout.push_back(CTxOut(paid_nValue,CScript() << origpubkey << OP_CHECKSIG));
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet(assetid2!=zeroid?'E':'S',assetid,assetid2,remaining_nValue,origpubkey)));
} else fprintf(stderr,"filltx not enough utxos\n");
}
}
return(0);
}

30
src/cc/CCauction.h Normal file
View File

@@ -0,0 +1,30 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_AUCTION_H
#define CC_AUCTION_H
#include "CCinclude.h"
#define EVAL_AUCTION 0xe8
bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
std::string AuctionPost(uint64_t txfee,uint256 itemhash,uint64_t minbid,char *title,char *description);
std::string AuctionBid(uint64_t txfee,uint256 itemhash,uint64_t amount);
std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid);
#endif

195
src/cc/CCcustom.cpp Normal file
View File

@@ -0,0 +1,195 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCinclude.h"
#include "CCassets.h"
#include "CCfaucet.h"
#include "CCrewards.h"
#include "CCdice.h"
#include "CCauction.h"
#include "CClotto.h"
#include "CCponzi.h"
/*
CCcustom has most of the functions that need to be extended to create a new CC contract.
A CC scriptPubKey can only be spent if it is properly signed and validated. By constraining the vins and vouts, it is possible to implement a variety of functionality. CC vouts have an otherwise non-standard form, but it is properly supported by the enhanced bitcoin protocol code as a "cryptoconditions" output and the same pubkey will create a different address.
This allows creation of a special address(es) for each contract type, which has the privkey public. That allows anybody to properly sign and spend it, but with the constraints on what is allowed in the validation code, the contract functionality can be implemented.
what needs to be done to add a new contract:
1. add EVAL_CODE to eval.h
2. initialize the variables in the CCinit function below
3. write a Validate function to reject any unsanctioned usage of vin/vout
4. make helper functions to create rawtx for RPC functions
5. add rpc calls to rpcserver.cpp and rpcserver.h and in one of the rpc.cpp files
6. add the new .cpp files to src/Makefile.am
IMPORTANT: make sure that all CC inputs and CC outputs are properly accounted for and reconcile to the satoshi. The built in utxo management will enforce overall vin/vout constraints but it wont know anything about the CC constraints. That is what your Validate function needs to do.
Generally speaking, there will be normal coins that change into CC outputs, CC outputs that go back to being normal coins, CC outputs that are spent to new CC outputs.
Make sure both the CC coins and normal coins are preserved and follow the rules that make sense. It is a good idea to define specific roles for specific vins and vouts to reduce the complexity of validation.
*/
//BTCD Address: RAssetsAtGnvwgK9gVHBbAU4sVTah1hAm5
//BTCD Privkey: UvtvQVgVScXEYm4J3r4nE4nbFuGXSVM5pKec8VWXwgG9dmpWBuDh
//BTCD Address: RSavingsEYcivt2DFsxsKeCjqArV6oVtVZ
//BTCD Privkey: Ux6XQekTxokko6gZHz24B7PUsmUQtWFzG2W9nUA8jba7UoVbPBF4
// Assets, aka Tokens
#define FUNCNAME IsAssetsInput
#define EVALCODE EVAL_ASSETS
const char *AssetsCCaddr = "RGKRjeTBw4LYFotSDLT6RWzMHbhXri6BG6";
const char *AssetsNormaladdr = "RFYE2yL3KknWdHK6uNhvWacYsCUtwzjY3u";
char AssetsCChexstr[67] = { "02adf84e0e075cf90868bd4e3d34a03420e034719649c41f371fc70d8e33aa2702" };
uint8_t AssetsCCpriv[32] = { 0x9b, 0x17, 0x66, 0xe5, 0x82, 0x66, 0xac, 0xb6, 0xba, 0x43, 0x83, 0x74, 0xf7, 0x63, 0x11, 0x3b, 0xf0, 0xf3, 0x50, 0x6f, 0xd9, 0x6b, 0x67, 0x85, 0xf9, 0x7a, 0xf0, 0x54, 0x4d, 0xb1, 0x30, 0x77 };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
// Faucet
#define FUNCNAME IsFaucetInput
#define EVALCODE EVAL_FAUCET
const char *FaucetCCaddr = "R9zHrofhRbub7ER77B7NrVch3A63R39GuC";
const char *FaucetNormaladdr = "RKQV4oYs4rvxAWx1J43VnT73rSTVtUeckk";
char FaucetCChexstr[67] = { "03682b255c40d0cde8faee381a1a50bbb89980ff24539cb8518e294d3a63cefe12" };
uint8_t FaucetCCpriv[32] = { 0xd4, 0x4f, 0xf2, 0x31, 0x71, 0x7d, 0x28, 0x02, 0x4b, 0xc7, 0xdd, 0x71, 0xa0, 0x39, 0xc4, 0xbe, 0x1a, 0xfe, 0xeb, 0xc2, 0x46, 0xda, 0x76, 0xf8, 0x07, 0x53, 0x3d, 0x96, 0xb4, 0xca, 0xa0, 0xe9 };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
// Rewards
#define FUNCNAME IsRewardsInput
#define EVALCODE EVAL_REWARDS
const char *RewardsCCaddr = "RTsRBYL1HSvMoE3qtBJkyiswdVaWkm8YTK";
const char *RewardsNormaladdr = "RMgye9jeczNjQx9Uzq8no8pTLiCSwuHwkz";
char RewardsCChexstr[67] = { "03da60379d924c2c30ac290d2a86c2ead128cb7bd571f69211cb95356e2dcc5eb9" };
uint8_t RewardsCCpriv[32] = { 0x82, 0xf5, 0xd2, 0xe7, 0xd6, 0x99, 0x33, 0x77, 0xfb, 0x80, 0x00, 0x97, 0x23, 0x3d, 0x1e, 0x6f, 0x61, 0xa9, 0xb5, 0x2e, 0x5e, 0xb4, 0x96, 0x6f, 0xbc, 0xed, 0x6b, 0xe2, 0xbb, 0x7b, 0x4b, 0xb3 };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
// Dice
#define FUNCNAME IsDiceInput
#define EVALCODE EVAL_DICE
const char *DiceCCaddr = "REabWB7KjFN5C3LFMZ5odExHPenYzHLtVw";
const char *DiceNormaladdr = "RLEe8f7Eg3TDuXii9BmNiiiaVGraHUt25c";
char DiceCChexstr[67] = { "039d966927cfdadab3ee6c56da63c21f17ea753dde4b3dfd41487103e24b27e94e" };
uint8_t DiceCCpriv[32] = { 0x0e, 0xe8, 0xf5, 0xb4, 0x3d, 0x25, 0xcc, 0x35, 0xd1, 0xf1, 0x2f, 0x04, 0x5f, 0x01, 0x26, 0xb8, 0xd1, 0xac, 0x3a, 0x5a, 0xea, 0xe0, 0x25, 0xa2, 0x8f, 0x2a, 0x8e, 0x0e, 0xf9, 0x34, 0xfa, 0x77 };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
// Lotto
#define FUNCNAME IsLottoInput
#define EVALCODE EVAL_LOTTO
const char *LottoCCaddr = "RNXZxgyWSAE6XS3qGnTaf5dVNCxnYzhPrg";
const char *LottoNormaladdr = "RLW6hhRqBZZMBndnyPv29Yg3krh6iBYCyg";
char LottoCChexstr[67] = { "03f72d2c4db440df1e706502b09ca5fec73ffe954ea1883e4049e98da68690d98f" };
uint8_t LottoCCpriv[32] = { 0xb4, 0xac, 0xc2, 0xd9, 0x67, 0x34, 0xd7, 0x58, 0x80, 0x4e, 0x25, 0x55, 0xc0, 0x50, 0x66, 0x84, 0xbb, 0xa2, 0xe7, 0xc0, 0x39, 0x17, 0xb4, 0xc5, 0x07, 0xb7, 0x3f, 0xca, 0x07, 0xb0, 0x9a, 0xeb };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
// Ponzi
#define FUNCNAME IsPonziInput
#define EVALCODE EVAL_PONZI
const char *PonziCCaddr = "RUKTbLBeKgHkm3Ss4hKZP3ikuLW1xx7B2x";
const char *PonziNormaladdr = "RWSHRbxnJYLvDjpcQ2i8MekgP6h2ctTKaj";
char PonziCChexstr[67] = { "039b52d294b413b07f3643c1a28c5467901a76562d8b39a785910ae0a0f3043810" };
uint8_t PonziCCpriv[32] = { 0x11, 0xe1, 0xea, 0x3e, 0xdb, 0x36, 0xf0, 0xa8, 0xc6, 0x34, 0xe1, 0x21, 0xb8, 0x02, 0xb9, 0x4b, 0x12, 0x37, 0x8f, 0xa0, 0x86, 0x23, 0x50, 0xb2, 0x5f, 0xe4, 0xe7, 0x36, 0x0f, 0xda, 0xae, 0xfc };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
// Auction
#define FUNCNAME IsAuctionInput
#define EVALCODE EVAL_AUCTION
const char *AuctionCCaddr = "RL4YPX7JYG3FnvoPqWF2pn3nQknH5NWEwx";
const char *AuctionNormaladdr = "RFtVDNmdTZBTNZdmFRbfBgJ6LitgTghikL";
char AuctionCChexstr[67] = { "037eefe050c14cb60ae65d5b2f69eaa1c9006826d729bc0957bdc3024e3ca1dbe6" };
uint8_t AuctionCCpriv[32] = { 0x8c, 0x1b, 0xb7, 0x8c, 0x02, 0xa3, 0x9d, 0x21, 0x28, 0x59, 0xf5, 0xea, 0xda, 0xec, 0x0d, 0x11, 0xcd, 0x38, 0x47, 0xac, 0x0b, 0x6f, 0x19, 0xc0, 0x24, 0x36, 0xbf, 0x1c, 0x0a, 0x06, 0x31, 0xfb };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode)
{
cp->evalcode = evalcode;
switch ( evalcode )
{
case EVAL_ASSETS:
strcpy(cp->unspendableCCaddr,AssetsCCaddr);
strcpy(cp->normaladdr,AssetsNormaladdr);
strcpy(cp->CChexstr,AssetsCChexstr);
memcpy(cp->CCpriv,AssetsCCpriv,32);
cp->validate = AssetsValidate;
cp->ismyvin = IsAssetsInput;
break;
case EVAL_FAUCET:
strcpy(cp->unspendableCCaddr,FaucetCCaddr);
strcpy(cp->normaladdr,FaucetNormaladdr);
strcpy(cp->CChexstr,FaucetCChexstr);
memcpy(cp->CCpriv,FaucetCCpriv,32);
cp->validate = FaucetValidate;
cp->ismyvin = IsFaucetInput;
break;
case EVAL_REWARDS:
strcpy(cp->unspendableCCaddr,RewardsCCaddr);
strcpy(cp->normaladdr,RewardsNormaladdr);
strcpy(cp->CChexstr,RewardsCChexstr);
memcpy(cp->CCpriv,RewardsCCpriv,32);
cp->validate = RewardsValidate;
cp->ismyvin = IsRewardsInput;
break;
case EVAL_DICE:
strcpy(cp->unspendableCCaddr,DiceCCaddr);
strcpy(cp->normaladdr,DiceNormaladdr);
strcpy(cp->CChexstr,DiceCChexstr);
memcpy(cp->CCpriv,DiceCCpriv,32);
cp->validate = DiceValidate;
cp->ismyvin = IsDiceInput;
break;
case EVAL_LOTTO:
strcpy(cp->unspendableCCaddr,LottoCCaddr);
strcpy(cp->normaladdr,LottoNormaladdr);
strcpy(cp->CChexstr,LottoCChexstr);
memcpy(cp->CCpriv,LottoCCpriv,32);
cp->validate = LottoValidate;
cp->ismyvin = IsLottoInput;
break;
case EVAL_PONZI:
strcpy(cp->unspendableCCaddr,PonziCCaddr);
strcpy(cp->normaladdr,PonziNormaladdr);
strcpy(cp->CChexstr,PonziCChexstr);
memcpy(cp->CCpriv,PonziCCpriv,32);
cp->validate = PonziValidate;
cp->ismyvin = IsPonziInput;
break;
case EVAL_AUCTION:
strcpy(cp->unspendableCCaddr,AuctionCCaddr);
strcpy(cp->normaladdr,AuctionNormaladdr);
strcpy(cp->CChexstr,AuctionCChexstr);
memcpy(cp->CCpriv,AuctionCCpriv,32);
cp->validate = AuctionValidate;
cp->ismyvin = IsAuctionInput;
break;
}
return(cp);
}

17
src/cc/CCcustom.inc Normal file
View File

@@ -0,0 +1,17 @@
bool FUNCNAME(CScript const& scriptSig)
{
CC *cond;
if (!(cond = GetCryptoCondition(scriptSig)))
return false;
// Recurse the CC tree to find asset condition
auto findEval = [] (CC *cond, struct CCVisitor _) {
bool r = cc_typeId(cond) == CC_Eval && cond->codeLength == 1 && cond->code[0] == EVALCODE;
// false for a match, true for continue
return r ? 0 : 1;
};
CCVisitor visitor = {findEval, (uint8_t*)"", 0, NULL};
bool out =! cc_visit(cond, visitor);
cc_free(cond);
return out;
}

32
src/cc/CCdice.h Normal file
View File

@@ -0,0 +1,32 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_DICE_H
#define CC_DICE_H
#include "CCinclude.h"
#define EVAL_DICE 0xe6
bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds);
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks);
std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount);
UniValue DiceInfo(uint256 diceid);
UniValue DiceList();
#endif

30
src/cc/CCfaucet.h Normal file
View File

@@ -0,0 +1,30 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_FAUCET_H
#define CC_FAUCET_H
#include "CCinclude.h"
#define EVAL_FAUCET 0xe4
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
// CCcustom
std::string FaucetFund(uint64_t txfee,uint64_t funds);
std::string FaucetGet(uint64_t txfee);
#endif

82
src/cc/CCinclude.h Normal file
View File

@@ -0,0 +1,82 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_INCLUDE_H
#define CC_INCLUDE_H
#include <cc/eval.h>
#include <script/cc.h>
#include <script/script.h>
#include <cryptoconditions.h>
#include "../script/standard.h"
#include "../base58.h"
#include "../core_io.h"
#include "../script/sign.h"
#include "../wallet/wallet.h"
#include <univalue.h>
#include <exception>
#define SMALLVAL 0.000000000000001
struct CCcontract_info
{
uint256 prevtxid;
char unspendableCCaddr[64],CChexstr[72],normaladdr[64];
uint8_t CCpriv[32];
bool (*validate)(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
bool (*ismyvin)(CScript const& scriptSig);
uint8_t evalcode,didinit;
};
struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode);
#ifdef ENABLE_WALLET
extern CWallet* pwalletMain;
#endif
bool GetAddressUnspent(uint160 addressHash, int type,std::vector<std::pair<CAddressUnspentKey,CAddressUnspentValue> > &unspentOutputs);
static uint256 zeroid;
// CCcustom
CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv);
// CCutils
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk);
CC *MakeCCcond1(uint8_t evalcode,CPubKey pk);
CC* GetCryptoCondition(CScript const& scriptSig);
bool IsCCInput(CScript const& scriptSig);
int32_t unstringbits(char *buf,uint64_t bits);
uint64_t stringbits(char *str);
uint256 revuint256(uint256 txid);
char *uint256_str(char *dest,uint256 txid);
char *pubkey33_str(char *dest,uint8_t *pubkey33);
uint256 Parseuint256(char *hexstr);
CPubKey pubkey2pk(std::vector<uint8_t> pubkey);
bool GetCCaddress(struct CCcontract_info *cp,char *destaddr,CPubKey pk);
bool ConstrainVout(CTxOut vout,int32_t CCflag,char *cmpaddr,uint64_t nValue);
bool PreventCC(Eval* eval,const CTransaction &tx,int32_t preventCCvins,int32_t numvins,int32_t preventCCvouts,int32_t numvouts);
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
std::vector<uint8_t> Mypubkey();
bool Myprivkey(uint8_t myprivkey[]);
int64_t CCduration(uint256 txid);
// CCtx
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret);
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr);
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr);
uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,int32_t maxinputs);
uint64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout);
#endif

29
src/cc/CClotto.h Normal file
View File

@@ -0,0 +1,29 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_LOTTO_H
#define CC_LOTTO_H
#include "CCinclude.h"
#define EVAL_LOTTO 0xe9
bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
std::string LottoTicket(uint64_t txfee,uint64_t numtickets);
std::string LottoWinner(uint64_t txfee);
#endif

29
src/cc/CCponzi.h Normal file
View File

@@ -0,0 +1,29 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_PONZI_H
#define CC_PONZI_H
#include "CCinclude.h"
#define EVAL_PONZI 0xe7
bool PonziValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
std::string PonziBuy(uint64_t txfee,uint64_t amount);
std::string PonziClaim(uint64_t txfee);
#endif

33
src/cc/CCrewards.h Normal file
View File

@@ -0,0 +1,33 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_REWARDS_H
#define CC_REWARDS_H
#include "CCinclude.h"
#define EVAL_REWARDS 0xe5
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
UniValue RewardsInfo(uint256 rewardid);
UniValue RewardsList();
std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit);
std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount);
std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount);
std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid);
#endif

235
src/cc/CCtx.cpp Normal file
View File

@@ -0,0 +1,235 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCinclude.h"
/*
FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn.
This allows the contract transaction functions to create the appropriate vins and vouts and have FinalizeCCTx create a properly signed transaction.
By using -addressindex=1, it allows tracking of all the CC addresses
*/
bool SignTx(CMutableTransaction &mtx,int32_t vini,uint64_t utxovalue,const CScript scriptPubKey)
{
#ifdef ENABLE_WALLET
CTransaction txNewConst(mtx); SignatureData sigdata; const CKeyStore& keystore = *pwalletMain;
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
if ( ProduceSignature(TransactionSignatureCreator(&keystore,&txNewConst,vini,utxovalue,SIGHASH_ALL),scriptPubKey,sigdata,consensusBranchId) != 0 )
{
UpdateTransaction(mtx,vini,sigdata);
return(true);
} else fprintf(stderr,"signing error for SignTx vini.%d %.8f\n",vini,(double)utxovalue/COIN);
#else
return(false);
#endif
}
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
{
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0,utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0; int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64]; uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*cond; CPubKey unspendablepk;
n = mtx.vout.size();
for (i=0; i<n; i++)
{
if ( mtx.vout[i].scriptPubKey.IsPayToCryptoCondition() == 0 )
normaloutputs += mtx.vout[i].nValue;
totaloutputs += mtx.vout[i].nValue;
}
if ( (n= mtx.vin.size()) > 64 )
{
fprintf(stderr,"FinalizeCCTx: %d is too many vins\n",n);
return(0);
}
Myprivkey(myprivkey);
unspendablepk = GetUnspendable(cp,unspendablepriv);
GetCCaddress(cp,myaddr,mypk);
mycond = MakeCCcond1(cp->evalcode,mypk);
GetCCaddress(cp,unspendable,unspendablepk);
othercond = MakeCCcond1(cp->evalcode,unspendablepk);
//fprintf(stderr,"myCCaddr.(%s) %p vs unspendable.(%s) %p\n",myaddr,mycond,unspendable,othercond);
memset(utxovalues,0,sizeof(utxovalues));
for (i=0; i<n; i++)
{
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
{
utxovout = mtx.vin[i].prevout.n;
utxovalues[i] = vintx.vout[utxovout].nValue;
totalinputs += utxovalues[i];
if ( vintx.vout[utxovout].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
//fprintf(stderr,"vin.%d is normal %.8f\n",i,(double)utxovalues[i]/COIN);
normalinputs += utxovalues[i];
vinimask |= (1LL << i);
}
else
{
mask |= (1LL << i);
}
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
}
nmask = (1LL << n) - 1;
if ( (mask & nmask) != (CCmask & nmask) )
fprintf(stderr,"mask.%llx vs CCmask.%llx %llx %llx %llx\n",(long long)(mask & nmask),(long long)(CCmask & nmask),(long long)mask,(long long)CCmask,(long long)nmask);
if ( totalinputs >= totaloutputs+2*txfee )
{
change = totalinputs - (totaloutputs+txfee);
mtx.vout.push_back(CTxOut(change,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
}
if ( opret.size() > 0 )
mtx.vout.push_back(CTxOut(0,opret));
PrecomputedTransactionData txdata(mtx);
n = mtx.vin.size();
for (i=0; i<n; i++)
{
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
{
utxovout = mtx.vin[i].prevout.n;
if ( vintx.vout[utxovout].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
if ( SignTx(mtx,i,vintx.vout[utxovout].nValue,vintx.vout[utxovout].scriptPubKey) == 0 )
fprintf(stderr,"signing error for vini.%d of %llx\n",i,(long long)vinimask);
}
else
{
Getscriptaddress(destaddr,vintx.vout[utxovout].scriptPubKey);
//fprintf(stderr,"vin.%d is CC %.8f -> (%s)\n",i,(double)utxovalues[i]/COIN,destaddr);
if ( strcmp(destaddr,myaddr) == 0 )
{
privkey = myprivkey;
cond = mycond;
//fprintf(stderr,"my CC addr.(%s)\n",myaddr);
}
else if ( strcmp(destaddr,unspendable) == 0 )
{
privkey = unspendablepriv;
cond = othercond;
//fprintf(stderr,"unspendable CC addr.(%s)\n",unspendable);
}
else
{
fprintf(stderr,"vini.%d has unknown CC address.(%s)\n",i,destaddr);
continue;
}
uint256 sighash = SignatureHash(CCPubKey(cond), mtx, i, SIGHASH_ALL, utxovalues[i],consensusBranchId, &txdata);
if ( cc_signTreeSecp256k1Msg32(cond,privkey,sighash.begin()) != 0 )
{
//int32_t z;
//for (z=0; z<32; z++)
// fprintf(stderr,"%02x",((uint8_t *)sighash.begin())[z]);
//fprintf(stderr," sighash, ");
//for (z=0; z<32; z++)
// fprintf(stderr,"%02x",privkey[z]);
//fprintf(stderr," signed with privkey\n");
mtx.vin[i].scriptSig = CCSig(cond);
}
else fprintf(stderr,"vini.%d has CC signing error address.(%s)\n",i,destaddr);
}
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
}
if ( mycond != 0 )
cc_free(mycond);
if ( othercond != 0 )
cc_free(othercond);
std::string strHex = EncodeHexTx(mtx);
if ( strHex.size() > 0 )
return(strHex);
else return(0);
}
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr)
{
int32_t type=0,i,n; char *ptr; std::string addrstr; uint160 hashBytes; std::vector<std::pair<uint160, int> > addresses;
n = (int32_t)strlen(coinaddr);
addrstr.resize(n+1);
ptr = (char *)addrstr.data();
for (i=0; i<=n; i++)
ptr[i] = coinaddr[i];
CBitcoinAddress address(addrstr);
if ( address.GetIndexKey(hashBytes, type) == 0 )
return;
addresses.push_back(std::make_pair(hashBytes,type));
for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++)
{
if ( GetAddressUnspent((*it).first, (*it).second, unspentOutputs) == 0 )
return;
}
}
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr)
{
int32_t type=0,i,n; char *ptr; std::string addrstr; uint160 hashBytes; std::vector<std::pair<uint160, int> > addresses;
n = (int32_t)strlen(coinaddr);
addrstr.resize(n+1);
ptr = (char *)addrstr.data();
for (i=0; i<=n; i++)
ptr[i] = coinaddr[i];
CBitcoinAddress address(addrstr);
if ( address.GetIndexKey(hashBytes, type) == 0 )
return;
addresses.push_back(std::make_pair(hashBytes,type));
for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++)
{
if ( GetAddressIndex((*it).first, (*it).second, addressIndex) == 0 )
return;
}
}
uint64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout)
{
uint256 txid; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
if ( txid == utxotxid && utxovout == it->first.index )
return(it->second.satoshis);
}
return(0);
}
uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,int32_t maxinputs)
{
int32_t vout,j,n = 0; uint64_t nValue,totalinputs = 0; uint256 txid; std::vector<COutput> vecOutputs;
#ifdef ENABLE_WALLET
const CKeyStore& keystore = *pwalletMain;
assert(pwalletMain != NULL);
LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
BOOST_FOREACH(const COutput& out, vecOutputs)
{
if ( out.fSpendable != 0 )
{
txid = out.tx->GetHash();
vout = out.i;
for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;
if ( j != mtx.vin.size() )
continue;
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
nValue = out.tx->vout[out.i].nValue;
totalinputs += nValue;
n++;
if ( totalinputs >= total || n >= maxinputs )
break;
}
}
if ( totalinputs >= total )
return(totalinputs);
#endif
return(0);
}

298
src/cc/CCutils.cpp Normal file
View File

@@ -0,0 +1,298 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCinclude.h"
/*
CCutils has low level functions that are universally useful for all contracts.
*/
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk)
{
CTxOut vout;
CC *payoutCond = MakeCCcond1(evalcode,pk);
vout = CTxOut(nValue,CCPubKey(payoutCond));
cc_free(payoutCond);
return(vout);
}
CC *MakeCCcond1(uint8_t evalcode,CPubKey pk)
{
std::vector<CC*> pks;
pks.push_back(CCNewSecp256k1(pk));
CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode));
CC *Sig = CCNewThreshold(1, pks);
return CCNewThreshold(2, {condCC, Sig});
}
CC* GetCryptoCondition(CScript const& scriptSig)
{
auto pc = scriptSig.begin();
opcodetype opcode;
std::vector<unsigned char> ffbin;
if (scriptSig.GetOp(pc, opcode, ffbin))
return cc_readFulfillmentBinary((uint8_t*)ffbin.data(), ffbin.size()-1);
}
bool IsCCInput(CScript const& scriptSig)
{
CC *cond;
if ( (cond= GetCryptoCondition(scriptSig)) == 0 )
return false;
cc_free(cond);
return true;
}
int32_t unstringbits(char *buf,uint64_t bits)
{
int32_t i;
for (i=0; i<8; i++,bits>>=8)
if ( (buf[i]= (char)(bits & 0xff)) == 0 )
break;
buf[i] = 0;
return(i);
}
uint64_t stringbits(char *str)
{
uint64_t bits = 0;
if ( str == 0 )
return(0);
int32_t i,n = (int32_t)strlen(str);
if ( n > 8 )
n = 8;
for (i=n-1; i>=0; i--)
bits = (bits << 8) | (str[i] & 0xff);
//printf("(%s) -> %llx %llu\n",str,(long long)bits,(long long)bits);
return(bits);
}
uint256 revuint256(uint256 txid)
{
uint256 revtxid; int32_t i;
for (i=31; i>=0; i--)
((uint8_t *)&revtxid)[31-i] = ((uint8_t *)&txid)[i];
return(revtxid);
}
char *uint256_str(char *dest,uint256 txid)
{
int32_t i,j=0;
for (i=31; i>=0; i--)
sprintf(&dest[j++ * 2],"%02x",((uint8_t *)&txid)[i]);
dest[64] = 0;
return(dest);
}
char *pubkey33_str(char *dest,uint8_t *pubkey33)
{
int32_t i;
if ( pubkey33 != 0 )
{
for (i=0; i<33; i++)
sprintf(&dest[i * 2],"%02x",pubkey33[i]);
} else dest[0] = 0;
return(dest);
}
uint256 Parseuint256(char *hexstr)
{
uint256 txid; int32_t i; std::vector<unsigned char> txidbytes(ParseHex(hexstr));
memset(&txid,0,sizeof(txid));
if ( strlen(hexstr) == 64 )
{
for (i=31; i>=0; i--)
((uint8_t *)&txid)[31-i] = ((uint8_t *)txidbytes.data())[i];
}
return(txid);
}
CPubKey pubkey2pk(std::vector<uint8_t> pubkey)
{
CPubKey pk; int32_t i,n; uint8_t *dest,*pubkey33;
n = pubkey.size();
dest = (uint8_t *)pk.begin();
pubkey33 = (uint8_t *)pubkey.data();
for (i=0; i<n; i++)
dest[i] = pubkey33[i];
return(pk);
}
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
{
CTxDestination address; txnouttype whichType;
if ( ExtractDestination(scriptPubKey,address) != 0 )
{
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
return(true);
}
fprintf(stderr,"ExtractDestination failed\n");
return(false);
}
bool GetCCaddress(struct CCcontract_info *cp,char *destaddr,CPubKey pk)
{
CC *payoutCond;
destaddr[0] = 0;
if ( pk.size() == 0 )
pk = GetUnspendable(cp,0);
if ( (payoutCond= MakeCCcond1(cp->evalcode,pk)) != 0 )
{
Getscriptaddress(destaddr,CCPubKey(payoutCond));
cc_free(payoutCond);
}
return(destaddr[0] != 0);
}
bool ConstrainVout(CTxOut vout,int32_t CCflag,char *cmpaddr,uint64_t nValue)
{
char destaddr[64];
if ( vout.scriptPubKey.IsPayToCryptoCondition() != CCflag )
{
fprintf(stderr,"constrain vout error isCC %d vs %d CCflag\n",vout.scriptPubKey.IsPayToCryptoCondition(),CCflag);
return(false);
}
else if ( cmpaddr != 0 && (Getscriptaddress(destaddr,vout.scriptPubKey) == 0 || strcmp(destaddr,cmpaddr) != 0) )
{
fprintf(stderr,"constrain vout error addr %s vs %s\n",cmpaddr!=0?cmpaddr:"",destaddr!=0?destaddr:"");
return(false);
}
else if ( nValue != 0 && nValue != vout.nValue ) //(nValue == 0 && vout.nValue < 10000) || (
{
fprintf(stderr,"constrain vout error nValue %.8f vs %.8f\n",(double)nValue/COIN,(double)vout.nValue/COIN);
return(false);
}
else return(true);
}
bool PreventCC(Eval* eval,const CTransaction &tx,int32_t preventCCvins,int32_t numvins,int32_t preventCCvouts,int32_t numvouts)
{
int32_t i;
if ( preventCCvins >= 0 )
{
for (i=preventCCvins; i<numvins; i++)
{
if ( IsCCInput(tx.vin[i].scriptSig) != 0 )
return eval->Invalid("invalid CC vin");
}
}
if ( preventCCvouts >= 0 )
{
for (i=preventCCvouts; i<numvouts; i++)
{
if ( tx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 )
return eval->Invalid("invalid CC vout");
}
}
return(true);
}
std::vector<uint8_t> Mypubkey()
{
extern uint8_t NOTARY_PUBKEY33[33];
std::vector<uint8_t> pubkey; int32_t i; uint8_t *dest,*pubkey33;
pubkey33 = NOTARY_PUBKEY33;
pubkey.resize(33);
dest = pubkey.data();
for (i=0; i<33; i++)
dest[i] = pubkey33[i];
return(pubkey);
}
bool Myprivkey(uint8_t myprivkey[])
{
char coinaddr[64]; std::string strAddress; char *dest; int32_t i,n; CBitcoinAddress address; CKeyID keyID; CKey vchSecret;
if ( Getscriptaddress(coinaddr,CScript() << Mypubkey() << OP_CHECKSIG) != 0 )
{
n = (int32_t)strlen(coinaddr);
strAddress.resize(n+1);
dest = (char *)strAddress.data();
for (i=0; i<n; i++)
dest[i] = coinaddr[i];
dest[i] = 0;
if ( address.SetString(strAddress) != 0 && address.GetKeyID(keyID) != 0 )
{
#ifdef ENABLE_WALLET
if ( pwalletMain->GetKey(keyID,vchSecret) != 0 )
{
memcpy(myprivkey,vchSecret.begin(),32);
if ( 0 )
{
for (i=0; i<32; i++)
fprintf(stderr,"0x%02x, ",myprivkey[i]);
fprintf(stderr," found privkey!\n");
}
return(true);
}
#endif
}
}
fprintf(stderr,"privkey for the -pubkey= address is not in the wallet, importprivkey!\n");
return(false);
}
CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv)
{
if ( unspendablepriv != 0 )
memcpy(unspendablepriv,cp->CCpriv,32);
return(pubkey2pk(ParseHex(cp->CChexstr)));
}
bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull,const CTransaction &ctx, unsigned int nIn)
{
CTransaction createTx; uint256 txid,assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector<uint8_t> origpubkey;
txid = ctx.GetHash();
if ( txid == cp->prevtxid )
return(true);
if ( paramsNull.size() != 0 ) // Don't expect params
return eval->Invalid("Cannot have params");
else if ( ctx.vout.size() == 0 )
return eval->Invalid("no-vouts");
else if ( (*cp->validate)(cp,eval,ctx) != 0 )
{
cp->prevtxid = txid;
return(true);
}
return(false);
}
int64_t CCduration(uint256 txid)
{
CTransaction tx; uint256 hashBlock; uint32_t txtime=0; char str[65]; CBlockIndex *pindex; int64_t duration = 0;
if ( GetTransaction(txid,tx,hashBlock,false) == 0 )
{
fprintf(stderr,"CCduration cant find duration txid %s\n",uint256_str(str,txid));
return(0);
}
else if ( hashBlock == zeroid )
{
fprintf(stderr,"CCduration no hashBlock for txid %s\n",uint256_str(str,txid));
return(0);
}
else if ( (pindex= mapBlockIndex[hashBlock]) == 0 || (txtime= pindex->nTime) == 0 )
{
fprintf(stderr,"CCduration no txtime %u %p for txid %s\n",txtime,pindex,uint256_str(str,txid));
return(0);
}
else if ( (pindex= chainActive.LastTip()) == 0 || pindex->nTime < txtime )
{
fprintf(stderr,"CCduration backwards timestamps %u %u for txid %s\n",(uint32_t)pindex->nTime,txtime,uint256_str(str,txid));
return(0);
}
duration = (pindex->nTime - txtime);
fprintf(stderr,"duration %d (%u - %u)\n",(int32_t)duration,(uint32_t)pindex->nTime,txtime);
return(duration);
}

367
src/cc/assets.cpp Normal file
View File

@@ -0,0 +1,367 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCassets.h"
/*
Assets can be created or transferred.
native coins are also locked in the EVAL_ASSETS address, so we need a strict rule on when utxo in the special address are native coins and when they are assets. The specific rule that must not be violated is that vout0 for 'b'/'B' funcid are native coins. All other utxo locked in the special address are assets.
To create an asset use CC EVAL_ASSETS to create a transaction where vout[0] funds the assets. Externally each satoshi can be interpreted to represent 1 asset, or 100 million satoshis for one asset with 8 decimals, and the other decimals in between. The interpretation of the number of decimals is left to the higher level usages.
Once created, the assetid is the txid of the create transaction and using the assetid/0 it can spend the assets to however many outputs it creates. The restriction is that the last output must be an opreturn with the assetid. The sum of all but the first output needs to add up to the total assetoshis input. The first output is ignored and used for change from txfee.
What this means is that vout 0 of the creation txid and vouts 1 ... n-2 for transfer vouts are assetoshi outputs.
There is a special type of transfer to an unspendable address, that locks the asset and creates an offer for all. The details specified in the opreturn. In order to be compatible with the signing restrictions, the "unspendable" address is actually an address whose privkey is known to all. Funds sent to this address can only be spent if the swap parameters are fulfilled, or if the original pubkey cancels the offer by spending it.
Types of transactions:
create name:description -> txid for assetid
transfer <pubkey> <assetid> -> [{address:amount}, ... ] // like withdraw api
selloffer <pubkey> <txid/vout> <amount> -> cancel or fillsell -> mempool txid or rejected, might not confirm
buyoffer <amount> <assetid> <required> -> cancelbuy or fillbuy -> mempool txid or rejected, might not confirm
exchange <pubkey> <txid/vout> <required> <required assetid> -> cancel or fillexchange -> mempool txid or rejected, might not confirm
assetsaddress <pubkey> // all assets end up in a special address for each pubkey
assetbalance <pubkey> <assetid>
assetutxos <pubkey> <assetid>
assetsbalances <pubkey>
asks <assetid>
bids <assetid>
swaps <assetid>
valid CC output: create or transfer or buyoffer or selloffer or exchange or cancel or fill
create
vin.0: normal input
vout.0: issuance assetoshis to CC
vout.1: tag sent to normal address of AssetsCCaddress
vout.2: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['c'] [origpubkey] "<assetname>" "<description>"
transfer
vin.0: normal input
vin.1 .. vin.n-1: valid CC outputs
vout.0 to n-2: assetoshis output to CC
vout.n-2: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['t'] [assetid]
buyoffer:
vins.*: normal inputs (bid + change)
vout.0: amount of bid to unspendable
vout.1: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['b'] [assetid] [amount of asset required] [origpubkey]
cancelbuy:
vin.0: normal input
vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0]
vout.0: vin.1 value to original pubkey buyTx.vout[0].nValue -> [origpubkey]
vout.1: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['o'] [assetid]
fillbuy:
vin.0: normal input
vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0]
vin.2+: valid CC output satisfies buyoffer (*tx.vin[2])->nValue
vout.0: remaining amount of bid to unspendable
vout.1: vin.1 value to signer of vin.2
vout.2: vin.2 assetoshis to original pubkey
vout.3: CC output for assetoshis change (if any)
vout.4: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['B'] [assetid] [remaining asset required] [origpubkey]
selloffer:
vin.0: normal input
vin.1+: valid CC output for sale
vout.0: vin.1 assetoshis output to CC to unspendable
vout.1: CC output for change (if any)
vout.2: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['s'] [assetid] [amount of native coin required] [origpubkey]
exchange:
vin.0: normal input
vin.1+: valid CC output
vout.0: vin.1 assetoshis output to CC to unspendable
vout.1: CC output for change (if any)
vout.2: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['e'] [assetid] [assetid2] [amount of asset2 required] [origpubkey]
cancel:
vin.0: normal input
vin.1: unspendable.(vout.0 from exchange or selloffer) sellTx/exchangeTx.vout[0] inputTx
vout.0: vin.1 assetoshis to original pubkey CC sellTx/exchangeTx.vout[0].nValue -> [origpubkey]
vout.1: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['x'] [assetid]
fillsell:
vin.0: normal input
vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0]
vin.2+: normal output that satisfies selloffer (*tx.vin[2])->nValue
vout.0: remaining assetoshis -> unspendable
vout.1: vin.1 assetoshis to signer of vin.2 sellTx.vout[0].nValue -> any
vout.2: vin.2 value to original pubkey [origpubkey]
vout.3: CC asset for change (if any)
vout.4: CC asset2 for change (if any) 'E' only
vout.5: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['S'] [assetid] [amount of coin still required] [origpubkey]
fillexchange:
vin.0: normal input
vin.1: unspendable.(vout.0 assetoshis from exchange) exchangeTx.vout[0]
vin.2+: valid CC assetid2 output that satisfies exchange (*tx.vin[2])->nValue
vout.0: remaining assetoshis -> unspendable
vout.1: vin.1 assetoshis to signer of vin.2 exchangeTx.vout[0].nValue -> any
vout.2: vin.2 assetoshis2 to original pubkey [origpubkey]
vout.3: normal output for change (if any)
vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
*/
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
static uint256 zero;
CTxDestination address; CTransaction vinTx,createTx; uint256 hashBlock,assetid,assetid2; int32_t i,starti,numvins,numvouts,preventCCvins,preventCCvouts; int64_t remaining_price,nValue,assetoshis,outputs,inputs,tmpprice,totalunits,ignore; std::vector<uint8_t> origpubkey,tmporigpubkey,ignorepubkey; uint8_t funcid; char destaddr[64],origaddr[64],CCaddr[64];
numvins = tx.vin.size();
numvouts = tx.vout.size();
outputs = inputs = 0;
preventCCvins = preventCCvouts = -1;
if ( (funcid= DecodeAssetOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,assetid2,remaining_price,origpubkey)) == 0 )
return eval->Invalid("Invalid opreturn payload");
fprintf(stderr,"AssetValidate (%c)\n",funcid);
if ( funcid != 'o' && funcid != 'x' && eval->GetTxUnconfirmed(assetid,createTx,hashBlock) == 0 )
return eval->Invalid("cant find asset create txid");
else if ( funcid != 'o' && funcid != 'x' && assetid2 != zero && eval->GetTxUnconfirmed(assetid2,createTx,hashBlock) == 0 )
return eval->Invalid("cant find asset2 create txid");
else if ( IsCCInput(tx.vin[0].scriptSig) != 0 )
return eval->Invalid("illegal asset vin0");
else if ( numvouts < 1 )
return eval->Invalid("no vouts");
else if ( funcid != 'c' )
{
if ( funcid == 't' )
starti = 0;
else starti = 1;
if ( assetid == zero )
return eval->Invalid("illegal assetid");
else if ( AssetExactAmounts(cp,inputs,starti,outputs,eval,tx,assetid) == false )
return eval->Invalid("asset inputs != outputs");
}
switch ( funcid )
{
case 'c': // create wont be called to be verified as it has no CC inputs
//vin.0: normal input
//vout.0: issuance assetoshis to CC
//vout.1: normal output for change (if any)
//vout.n-1: opreturn [EVAL_ASSETS] ['c'] [{"<assetname>":"<description>"}]
return eval->Invalid("unexpected AssetValidate for createasset");
break;
case 't': // transfer
//vin.0: normal input
//vin.1 .. vin.n-1: valid CC outputs
//vout.0 to n-2: assetoshis output to CC
//vout.n-2: normal output for change (if any)
//vout.n-1: opreturn [EVAL_ASSETS] ['t'] [assetid]
if ( inputs == 0 )
return eval->Invalid("no asset inputs for transfer");
fprintf(stderr,"transfer validated %.8f -> %.8f\n",(double)inputs/COIN,(double)outputs/COIN);
break;
case 'b': // buyoffer
//vins.*: normal inputs (bid + change)
//vout.0: amount of bid to unspendable
//vout.1: normal output for change (if any)
// vout.n-1: opreturn [EVAL_ASSETS] ['b'] [assetid] [amount of asset required] [origpubkey]
if ( remaining_price == 0 )
return eval->Invalid("illegal null amount for buyoffer");
else if ( ConstrainVout(tx.vout[0],1,cp->unspendableCCaddr,0) == 0 )
return eval->Invalid("invalid vout for buyoffer");
preventCCvins = 1;
preventCCvouts = 1;
fprintf(stderr,"buy offer validated to destaddr.(%s)\n",cp->unspendableCCaddr);
break;
case 'o': // cancelbuy
//vin.0: normal input
//vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0]
//vout.0: vin.1 value to original pubkey buyTx.vout[0].nValue -> [origpubkey]
//vout.1: normal output for change (if any)
//vout.n-1: opreturn [EVAL_ASSETS] ['o']
if ( (nValue= AssetValidateBuyvin(cp,eval,tmpprice,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 )
return(false);
else if ( ConstrainVout(tx.vout[0],0,origaddr,nValue) == 0 )
return eval->Invalid("invalid refund for cancelbuy");
preventCCvins = 2;
preventCCvouts = 0;
fprintf(stderr,"cancelbuy validated to origaddr.(%s)\n",origaddr);
break;
case 'B': // fillbuy:
//vin.0: normal input
//vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0]
//vin.2+: valid CC output satisfies buyoffer (*tx.vin[2])->nValue
//vout.0: remaining amount of bid to unspendable
//vout.1: vin.1 value to signer of vin.2
//vout.2: vin.2 assetoshis to original pubkey
//vout.3: CC output for assetoshis change (if any)
//vout.4: normal output for change (if any)
//vout.n-1: opreturn [EVAL_ASSETS] ['B'] [assetid] [remaining asset required] [origpubkey]
preventCCvouts = 4;
if ( (nValue= AssetValidateBuyvin(cp,eval,totalunits,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 )
return(false);
else if ( numvouts < 3 )
return eval->Invalid("not enough vouts for fillbuy");
else if ( tmporigpubkey != origpubkey )
return eval->Invalid("mismatched origpubkeys for fillbuy");
else
{
if ( nValue != tx.vout[0].nValue+tx.vout[1].nValue )
return eval->Invalid("locked value doesnt match vout0+1 fillbuy");
else if ( tx.vout[3].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( ConstrainVout(tx.vout[2],1,CCaddr,0) == 0 )
return eval->Invalid("vout2 doesnt go to origpubkey fillbuy");
else if ( inputs != tx.vout[2].nValue+tx.vout[3].nValue )
return eval->Invalid("asset inputs doesnt match vout2+3 fillbuy");
}
else if ( ConstrainVout(tx.vout[2],1,CCaddr,inputs) == 0 )
return eval->Invalid("vout2 doesnt match inputs fillbuy");
else if ( ConstrainVout(tx.vout[1],0,0,0) == 0 )
return eval->Invalid("vout1 is CC for fillbuy");
else if ( ValidateBidRemainder(remaining_price,tx.vout[0].nValue,nValue,tx.vout[1].nValue,tx.vout[2].nValue,totalunits) == false )
return eval->Invalid("mismatched remainder for fillbuy");
else if ( remaining_price != 0 )
{
if ( ConstrainVout(tx.vout[0],1,cp->unspendableCCaddr,0) == 0 )
return eval->Invalid("mismatched vout0 AssetsCCaddr for fillbuy");
}
}
fprintf(stderr,"fillbuy validated\n");
break;
case 's': // selloffer
case 'e': // exchange
//vin.0: normal input
//vin.1+: valid CC output for sale
//vout.0: vin.1 assetoshis output to CC to unspendable
//vout.1: normal output for change (if any)
//'s'.vout.n-1: opreturn [EVAL_ASSETS] ['s'] [assetid] [amount of native coin required] [origpubkey]
//'e'.vout.n-1: opreturn [EVAL_ASSETS] ['e'] [assetid] [assetid2] [amount of asset2 required] [origpubkey]
if ( remaining_price == 0 )
return eval->Invalid("illegal null remaining_price for selloffer");
else if ( ConstrainVout(tx.vout[0],1,(char *)cp->unspendableCCaddr,inputs) == 0 )
return eval->Invalid("mismatched vout0 AssetsCCaddr for selloffer");
//fprintf(stderr,"remaining.%d for sell\n",(int32_t)remaining_price);
preventCCvouts = 1;
break;
case 'x': // cancel
//vin.0: normal input
//vin.1: unspendable.(vout.0 from exchange or selloffer) sellTx/exchangeTx.vout[0] inputTx
//vout.0: vin.1 assetoshis to original pubkey CC sellTx/exchangeTx.vout[0].nValue -> [origpubkey]
//vout.1: normal output for change (if any)
//vout.n-1: opreturn [EVAL_ASSETS] ['x'] [assetid]
if ( (assetoshis= AssetValidateSellvin(cp,eval,tmpprice,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 )
return(false);
else if ( ConstrainVout(tx.vout[0],1,CCaddr,assetoshis) == 0 )
return eval->Invalid("invalid vout for cancel");
preventCCvins = 2;
preventCCvouts = 1;
break;
case 'S': // fillsell
//vin.0: normal input
//vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0]
//'S'.vin.2+: normal output that satisfies selloffer (*tx.vin[2])->nValue
//vout.0: remaining assetoshis -> unspendable
//vout.1: vin.1 assetoshis to signer of vin.2 sellTx.vout[0].nValue -> any
//'S'.vout.2: vin.2 value to original pubkey [origpubkey]
//vout.3: normal output for change (if any)
//'S'.vout.n-1: opreturn [EVAL_ASSETS] ['S'] [assetid] [amount of coin still required] [origpubkey]
if ( (assetoshis= AssetValidateSellvin(cp,eval,totalunits,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 )
return(false);
else if ( numvouts < 3 )
return eval->Invalid("not enough vouts for fillask");
else if ( tmporigpubkey != origpubkey )
return eval->Invalid("mismatched origpubkeys for fillask");
else
{
if ( assetoshis != tx.vout[0].nValue+tx.vout[1].nValue )
return eval->Invalid("locked value doesnt match vout0+1 fillask");
if ( ValidateAskRemainder(remaining_price,tx.vout[0].nValue,assetoshis,tx.vout[1].nValue,tx.vout[2].nValue,totalunits) == false )
return eval->Invalid("mismatched remainder for fillask");
else if ( ConstrainVout(tx.vout[1],1,0,0) == 0 )
return eval->Invalid("normal vout1 for fillask");
else if ( ConstrainVout(tx.vout[2],0,origaddr,0) == 0 )
return eval->Invalid("normal vout1 for fillask");
else if ( remaining_price != 0 )
{
if ( ConstrainVout(tx.vout[0],1,(char *)cp->unspendableCCaddr,0) == 0 )
return eval->Invalid("mismatched vout0 AssetsCCaddr for fill");
}
}
fprintf(stderr,"fill validated\n");
break;
case 'E': // fillexchange
//vin.0: normal input
//vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0]
//vin.2+: valid CC assetid2 output that satisfies exchange (*tx.vin[2])->nValue
//vout.0: remaining assetoshis -> unspendable
//vout.1: vin.1 assetoshis to signer of vin.2 sellTx.vout[0].nValue -> any
//vout.2: vin.2+ assetoshis2 to original pubkey [origpubkey]
//vout.3: CC output for asset2 change (if any)
//vout.3/4: normal output for change (if any)
//vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
if ( AssetExactAmounts(cp,inputs,1,outputs,eval,tx,assetid2) == false )
eval->Invalid("asset2 inputs != outputs");
if ( (assetoshis= AssetValidateSellvin(cp,eval,totalunits,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 )
return(false);
else if ( numvouts < 3 )
return eval->Invalid("not enough vouts for fillex");
else if ( tmporigpubkey != origpubkey )
return eval->Invalid("mismatched origpubkeys for fillex");
else
{
if ( assetoshis != tx.vout[0].nValue+tx.vout[1].nValue )
return eval->Invalid("locked value doesnt match vout0+1 fillex");
else if ( tx.vout[3].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( ConstrainVout(tx.vout[2],1,CCaddr,0) == 0 )
return eval->Invalid("vout2 doesnt go to origpubkey fillex");
else if ( inputs != tx.vout[2].nValue+tx.vout[3].nValue )
return eval->Invalid("asset inputs doesnt match vout2+3 fillex");
}
else if ( ConstrainVout(tx.vout[2],1,CCaddr,inputs) == 0 )
return eval->Invalid("vout2 doesnt match inputs fillex");
else if ( ConstrainVout(tx.vout[1],0,0,0) == 0 )
return eval->Invalid("vout1 is CC for fillex");
fprintf(stderr,"assets vout0 %llu, vin1 %llu, vout2 %llu -> orig, vout1 %llu, total %llu\n",(long long)tx.vout[0].nValue,(long long)assetoshis,(long long)tx.vout[2].nValue,(long long)tx.vout[1].nValue,(long long)totalunits);
if ( ValidateSwapRemainder(remaining_price,tx.vout[0].nValue,assetoshis,tx.vout[1].nValue,tx.vout[2].nValue,totalunits) == false )
return eval->Invalid("mismatched remainder for fillex");
else if ( ConstrainVout(tx.vout[1],1,0,0) == 0 )
return eval->Invalid("normal vout1 for fillex");
else if ( remaining_price != 0 )
{
if ( ConstrainVout(tx.vout[0],1,(char *)cp->unspendableCCaddr,0) == 0 )
return eval->Invalid("mismatched vout0 AssetsCCaddr for fillex");
}
}
fprintf(stderr,"fill validated\n");
break;
}
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}

203
src/cc/auction.cpp Normal file
View File

@@ -0,0 +1,203 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCauction.h"
#include "../txmempool.h"
/*
*/
// start of consensus code
uint64_t IsAuctionvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
bool AuctionExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
//fprintf(stderr,"vini.%d\n",i);
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
//fprintf(stderr,"vini.%d check mempool\n",i);
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("cant find vinTx");
else
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant Auction from mempool");
if ( (assetoshis= IsAuctionvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsAuctionvout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+COIN+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + COIN + txfee");
}
else return(true);
}
bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
{
//fprintf(stderr,"check vins\n");
for (i=0; i<numvins; i++)
{
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
{
fprintf(stderr,"Auctionget invalid vini\n");
return eval->Invalid("illegal normal vini");
}
}
//fprintf(stderr,"check amounts\n");
if ( AuctionExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"Auctionget invalid amount\n");
return false;
}
else
{
preventCCvouts = 1;
if ( IsAuctionvout(cp,tx,0) != 0 )
{
preventCCvouts++;
i = 1;
} else i = 0;
if ( tx.vout[i].nValue != COIN )
return eval->Invalid("invalid Auction output");
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"Auctionget validated\n");
else fprintf(stderr,"Auctionget invalid\n");
return(retval);
}
}
}
// end of consensus code
// helper functions for rpc calls in rpcwallet.cpp
uint64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
{
char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
// prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsAuctionvout(cp,vintx,(int32_t)it->first.index)) > 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
}
}
}
return(totalinputs);
}
std::string AuctionBid(uint64_t txfee,uint256 itemhash,uint64_t amount)
{
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_AUCTION);
if ( txfee == 0 )
txfee = 10000;
Auctionpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddAuctionInputs(cp,mtx,Auctionpk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_AUCTION,CCchange,Auctionpk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
} else fprintf(stderr,"cant find Auction inputs\n");
return(0);
}
std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid)
{
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_AUCTION);
if ( txfee == 0 )
txfee = 10000;
Auctionpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddAuctionInputs(cp,mtx,Auctionpk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_AUCTION,CCchange,Auctionpk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
} else fprintf(stderr,"cant find Auction inputs\n");
return(0);
}
std::string AuctionPost(uint64_t txfee,uint256 itemhash,uint64_t minbid,char *title,char *description)
{
CMutableTransaction mtx; CPubKey mypk,Auctionpk; uint64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_AUCTION);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
Auctionpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_AUCTION,funds,Auctionpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
return(0);
}

View File

@@ -1,9 +1,28 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include <cryptoconditions.h>
#include "hash.h"
#include "main.h"
#include "chain.h"
#include "streams.h"
#include "script/cc.h"
#include "cc/eval.h"
#include "cc/betprotocol.h"
#include "cc/eval.h"
#include "cc/utils.h"
#include "primitives/transaction.h"
@@ -137,3 +156,146 @@ bool GetOpReturnHash(CScript script, uint256 &hash)
hash = uint256(vHash);
return true;
}
/*
* Crypto-Condition EVAL method that verifies a payout against a transaction
* notarised on another chain.
*
* IN: params - condition params
* IN: importTx - Payout transaction on value chain (KMD)
* IN: nIn - index of input of stake
*
* importTx: Spends stakeTx with payouts from asset chain
*
* in 0: Spends Stake TX and contains ImportPayout CC
* out 0: OP_RETURN MomProof, disputeTx
* out 1-: arbitrary payouts
*
* disputeTx: Spends sessionTx.0 (opener on asset chain)
*
* in 0: spends sessionTx.0
* in 1-: anything
* out 0: OP_RETURN hash of payouts
* out 1-: anything
*/
bool Eval::ImportPayout(const std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn)
{
if (importTx.vout.size() == 0) return Invalid("no-vouts");
// load data from vout[0]
MoMProof proof;
CTransaction disputeTx;
{
std::vector<unsigned char> vopret;
GetOpReturnData(importTx.vout[0].scriptPubKey, vopret);
if (!E_UNMARSHAL(vopret, ss >> proof; ss >> disputeTx))
return Invalid("invalid-payload");
}
// Check disputeTx.0 shows correct payouts
{
uint256 givenPayoutsHash;
GetOpReturnHash(disputeTx.vout[0].scriptPubKey, givenPayoutsHash);
std::vector<CTxOut> payouts(importTx.vout.begin() + 1, importTx.vout.end());
if (givenPayoutsHash != SerializeHash(payouts))
return Invalid("wrong-payouts");
}
// Check disputeTx spends sessionTx.0
// condition ImportPayout params is session ID from other chain
{
uint256 sessionHash;
if (!E_UNMARSHAL(params, ss >> sessionHash))
return Invalid("malformed-params");
if (disputeTx.vin[0].prevout != COutPoint(sessionHash, 0))
return Invalid("wrong-session");
}
// Check disputeTx solves momproof from vout[0]
{
NotarisationData data(0);
if (!GetNotarisationData(proof.notarisationHash, data))
return Invalid("coudnt-load-mom");
if (data.MoM != proof.branch.Exec(disputeTx.GetHash()))
return Invalid("mom-check-fail");
}
return Valid();
}
/*
* Crypto-Condition EVAL method that resolves a dispute of a session
*
* IN: vm - AppVM virtual machine to verify states
* IN: params - condition params
* IN: disputeTx - transaction attempting to resolve dispute
* IN: nIn - index of input of dispute tx
*
* disputeTx: attempt to resolve a dispute
*
* in 0: Spends Session TX first output, reveals DisputeHeader
* out 0: OP_RETURN hash of payouts
*/
bool Eval::DisputePayout(AppVM &vm, std::vector<uint8_t> params, const CTransaction &disputeTx, unsigned int nIn)
{
if (disputeTx.vout.size() == 0) return Invalid("no-vouts");
// get payouts hash
uint256 payoutHash;
if (!GetOpReturnHash(disputeTx.vout[0].scriptPubKey, payoutHash))
return Invalid("invalid-payout-hash");
// load params
uint16_t waitBlocks;
std::vector<uint8_t> vmParams;
if (!E_UNMARSHAL(params, ss >> VARINT(waitBlocks); ss >> vmParams))
return Invalid("malformed-params");
// ensure that enough time has passed
{
CTransaction sessionTx;
CBlockIndex sessionBlock;
// if unconformed its too soon
if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock))
return Error("couldnt-get-parent");
if (GetCurrentHeight() < sessionBlock.nHeight + waitBlocks)
return Invalid("dispute-too-soon"); // Not yet
}
// get spends
std::vector<CTransaction> spends;
if (!GetSpendsConfirmed(disputeTx.vin[0].prevout.hash, spends))
return Error("couldnt-get-spends");
// verify result from VM
int maxLength = -1;
uint256 bestPayout;
for (int i=1; i<spends.size(); i++)
{
std::vector<unsigned char> vmState;
if (spends[i].vout.size() == 0) continue;
if (!GetOpReturnData(spends[i].vout[0].scriptPubKey, vmState)) continue;
auto out = vm.evaluate(vmParams, vmState);
uint256 resultHash = SerializeHash(out.second);
if (out.first > maxLength) {
maxLength = out.first;
bestPayout = resultHash;
}
// The below means that if for any reason there is a draw, the first dispute wins
else if (out.first == maxLength) {
if (bestPayout != payoutHash) {
fprintf(stderr, "WARNING: VM has multiple solutions of same length\n");
bestPayout = resultHash;
}
}
}
if (maxLength == -1) return Invalid("no-evidence");
return bestPayout == payoutHash ? Valid() : Invalid("wrong-payout");
}

View File

@@ -1,9 +1,23 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef BETPROTOCOL_H
#define BETPROTOCOL_H
#include "cc/eval.h"
#include "pubkey.h"
#include "primitives/block.h"
#include "primitives/transaction.h"
#include "cryptoconditions/include/cryptoconditions.h"
@@ -11,25 +25,18 @@
class MoMProof
{
public:
int nIndex;
std::vector<uint256> branch;
MerkleBranch branch;
uint256 notarisationHash;
MoMProof() {}
MoMProof(int i, std::vector<uint256> b, uint256 n) : notarisationHash(n), nIndex(i), branch(b) {}
uint256 Exec(uint256 hash) const { return CBlock::CheckMerkleBranch(hash, branch, nIndex); }
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(VARINT(nIndex));
READWRITE(branch);
READWRITE(notarisationHash);
}
};
class BetProtocol
{
protected:

512
src/cc/dice.cpp Normal file
View File

@@ -0,0 +1,512 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCdice.h"
/*
in order to implement a dice game, we need a source of entropy, reasonably fast completion time and a way to manage the utxos.
1. CC vout locks "house" funds with hash(entropy) + half of shared secret
2. bettor submits bet, with entropy, odds, houseid and sends combined amount into another CC vout.
3. house account sends funds to winner with proof of entropy
4. if timeout, bettor wins funds
2. and 3. can be done in mempool
*/
uint64_t DiceCalc(uint64_t amount,uint256 txid,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks)
{
/*uint64_t duration,reward = 0;
if ( (duration= CCduration(txid)) < minseconds )
{
return(0);
//duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24);
} else if ( duration > maxseconds )
maxseconds = duration;
reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100);
fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN);
return(reward);*/
return(0);
}
CScript EncodeDiceFundingOpRet(uint8_t funcid,uint64_t sbits,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks)
{
CScript opret; uint8_t evalcode = EVAL_DICE;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << sbits << minbet << maxbet << maxodds << forfeitblocks);
return(opret);
}
uint8_t DecodeDiceFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,int64_t &minbet,int64_t &maxbet,int64_t &maxodds,int64_t &forfeitblocks)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> minbet; ss >> maxbet; ss >> maxodds; ss >> forfeitblocks) != 0 )
{
if ( e == EVAL_DICE && f == 'F' )
return(f);
}
return(0);
}
CScript EncodeDiceOpRet(uint8_t funcid,uint64_t sbits,uint256 fundingtxid)
{
CScript opret; uint8_t evalcode = EVAL_DICE;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << sbits << fundingtxid);
return(opret);
}
uint8_t DecodeDiceOpRet(uint256 txid,const CScript &scriptPubKey,uint64_t &sbits,uint256 &fundingtxid)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid; int64_t minbet,maxbet,maxodds,forfeitblocks;
GetOpReturnData(scriptPubKey, vopret);
if ( vopret.size() > 2 )
{
script = (uint8_t *)vopret.data();
if ( script[0] == EVAL_DICE )
{
if ( script[1] == 'F' )
{
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> minbet; ss >> maxbet; ss >> maxodds; ss >> forfeitblocks) != 0 )
{
fundingtxid = txid;
return('F');
} else fprintf(stderr,"unmarshal error for F\n");
}
else if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> fundingtxid) != 0 )
{
if ( e == EVAL_DICE && (f == 'L' || f == 'U' || f == 'A') )
return(f);
else fprintf(stderr,"mismatched e.%02x f.(%c)\n",e,f);
}
} else fprintf(stderr,"script[0] %02x != EVAL_DICE\n",script[0]);
} else fprintf(stderr,"not enough opret.[%d]\n",(int32_t)vopret.size());
return(0);
}
uint64_t IsDicevout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
bool DiceExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("always should find vin, but didnt");
else
{
if ( hashBlock == zerohash )
return eval->Invalid("cant dice from mempool");
if ( (assetoshis= IsDicevout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsDicevout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + txfee");
}
else return(true);
}
bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
uint256 txid,fundingtxid,hashBlock; int64_t minbet,maxbet,maxodds,forfeitblocks; uint64_t sbits,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
{
txid = tx.GetHash();
if ( (funcid= DecodeDiceOpRet(txid,tx.vout[numvouts-1].scriptPubKey,sbits,fundingtxid)) != 0 )
{
if ( eval->GetTxUnconfirmed(fundingtxid,fundingTx,hashBlock) == 0 )
return eval->Invalid("cant find fundingtxid");
else if ( fundingTx.vout.size() > 0 && DecodeDiceFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,forfeitblocks) != 'F' )
return eval->Invalid("fundingTx not valid");
switch ( funcid )
{
case 'F':
//vins.*: normal inputs
//vout.0: CC vout for funding
//vout.1: normal marker vout for easy searching
//vout.2: normal change
//vout.n-1: opreturn 'F' sbits APR minseconds maxseconds mindeposit
return eval->Invalid("unexpected DiceValidate for createfunding");
break;
case 'A':
//vins.*: normal inputs
//vout.0: CC vout for funding
//vout.1: normal change
//vout.n-1: opreturn 'A' sbits fundingtxid
return eval->Invalid("unexpected DiceValidate for addfunding");
break;
case 'L':
//vins.*: normal inputs
//vout.0: CC vout for locked funds
//vout.1: normal output to unlock address
//vout.2: change
//vout.n-1: opreturn 'L' sbits fundingtxid
return eval->Invalid("unexpected DiceValidate for lock");
break;
case 'U':
//vin.0: locked funds CC vout.0 from lock
//vin.1+: funding CC vout.0 from 'F' and 'A' and 'U'
//vout.0: funding CC change
//vout.1: normal output to unlock address
//vout.n-1: opreturn 'U' sbits fundingtxid
for (i=0; i<numvins; i++)
{
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) == 0 )
return eval->Invalid("unexpected normal vin for unlock");
}
if ( DiceExactAmounts(cp,eval,tx,txfee+tx.vout[1].nValue) == 0 )
return false;
else if ( eval->GetTxUnconfirmed(tx.vin[0].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("always should find vin.0, but didnt");
else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
return eval->Invalid("lock tx vout.0 is normal output");
else if ( tx.vout.size() < 3 )
return eval->Invalid("unlock tx not enough vouts");
else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
return eval->Invalid("unlock tx vout.0 is normal output");
else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() != 0 )
return eval->Invalid("unlock tx vout.1 is CC output");
else if ( tx.vout[1].scriptPubKey != vinTx.vout[1].scriptPubKey )
return eval->Invalid("unlock tx vout.1 mismatched scriptPubKey");
amount = vinTx.vout[0].nValue;
reward = DiceCalc(amount,tx.vin[0].prevout.hash,minbet,maxbet,maxodds,forfeitblocks);
if ( tx.vout[1].nValue > amount+reward )
return eval->Invalid("unlock tx vout.1 isnt amount+reward");
preventCCvouts = 1;
break;
}
}
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}
return(true);
}
// 'L' vs 'F' and 'A'
uint64_t AddDiceInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
{
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
fprintf(stderr,"(%s) %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;
if ( j != mtx.vin.size() )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( (funcid= DecodeDiceOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
{
fprintf(stderr,"fundsflag.%d (%c) %.8f %.8f\n",fundsflag,funcid,(double)tx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN);
if ( fundsflag != 0 && funcid != 'F' && funcid != 'A' && funcid != 'U' )
continue;
else if ( fundsflag == 0 && (funcid != 'L' || tx.vout.size() < 4) )
continue;
if ( total != 0 && maxinputs != 0 )
{
if ( fundsflag == 0 )
scriptPubKey = tx.vout[1].scriptPubKey;
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
}
totalinputs += it->second.satoshis;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} else fprintf(stderr,"null funcid\n");
}
}
return(totalinputs);
}
uint64_t DicePlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid)
{
char coinaddr[64]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( (funcid= DecodeDiceOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
{
if ( (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid )
{
if ( refsbits == sbits && (nValue= IsDicevout(cp,tx,vout)) > 0 )
totalinputs += nValue;
else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN);
} //else fprintf(stderr,"else case\n");
} else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN);
}
}
return(totalinputs);
}
bool DicePlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey dicepk,int64_t &minbet,int64_t &maxbet,int64_t &maxodds,int64_t &forfeitblocks)
{
char CCaddr[64]; uint64_t sbits; uint256 txid,hashBlock; CTransaction tx;
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
GetCCaddress(cp,CCaddr,dicepk);
SetCCtxids(txids,CCaddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{
//int height = it->first.blockHeight;
txid = it->first.txhash;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 )
{
if ( DecodeDiceFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,forfeitblocks) == 'F' )
{
if ( sbits == refsbits )
return(true);
}
}
}
return(false);
}
UniValue DiceInfo(uint256 diceid)
{
UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; int64_t minbet,maxbet,maxodds,forfeitblocks; uint64_t sbits; char str[67],numstr[65];
if ( GetTransaction(diceid,vintx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
result.push_back(Pair("error","cant find fundingtxid"));
return(result);
}
if ( vintx.vout.size() > 0 && DecodeDiceFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,forfeitblocks) == 0 )
{
fprintf(stderr,"fundingtxid isnt dice creation txid\n");
result.push_back(Pair("error","fundingtxid isnt dice creation txid"));
return(result);
}
result.push_back(Pair("result","success"));
result.push_back(Pair("fundingtxid",uint256_str(str,diceid)));
unstringbits(str,sbits);
result.push_back(Pair("name",str));
result.push_back(Pair("sbits",sbits));
sprintf(numstr,"%.8f",(double)minbet/COIN);
result.push_back(Pair("minbet",numstr));
sprintf(numstr,"%.8f",(double)maxbet/COIN);
result.push_back(Pair("maxbet",numstr));
result.push_back(Pair("maxodds",maxodds));
result.push_back(Pair("forfeitblocks",forfeitblocks));
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN);
result.push_back(Pair("funding",numstr));
return(result);
}
UniValue DiceList()
{
UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction vintx; uint64_t sbits; int64_t minbet,maxbet,maxodds,forfeitblocks; char str[65];
cp = CCinit(&C,EVAL_DICE);
SetCCtxids(addressIndex,cp->normaladdr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeDiceFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,forfeitblocks) != 0 )
{
result.push_back(uint256_str(str,txid));
}
}
}
return(result);
}
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks)
{
CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t a,b,c,d; struct CCcontract_info *cp,C;
if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || forfeitblocks < 0 || forfeitblocks > 1440 )
{
fprintf(stderr,"negative parameter error\n");
return(0);
}
cp = CCinit(&C,EVAL_DICE);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
dicepk = GetUnspendable(cp,0);
sbits = stringbits(planstr);
if ( DicePlanExists(cp,sbits,dicepk,a,b,c,d) != 0 )
{
fprintf(stderr,"Dice plan (%s) already exists\n",planstr);
return(0);
}
if ( AddNormalinputs(mtx,mypk,funds+2*txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,dicepk));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(dicepk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceFundingOpRet('F',sbits,minbet,maxbet,maxodds,forfeitblocks)));
}
fprintf(stderr,"cant find enough inputs\n");
return(0);
}
std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
{
CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t a,b,c,d; struct CCcontract_info *cp,C;
if ( amount < 0 )
{
fprintf(stderr,"negative parameter error\n");
return(0);
}
cp = CCinit(&C,EVAL_DICE);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
dicepk = GetUnspendable(cp,0);
sbits = stringbits(planstr);
if ( DicePlanExists(cp,sbits,dicepk,a,b,c,d) == 0 )
{
fprintf(stderr,"Dice plan %s doesnt exist\n",planstr);
return(0);
}
sbits = stringbits(planstr);
if ( AddNormalinputs(mtx,mypk,amount+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,dicepk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceOpRet('A',sbits,fundingtxid)));
} else fprintf(stderr,"cant find enough inputs\n");
fprintf(stderr,"cant find fundingtxid\n");
return(0);
}
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds)
{
CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t funding,minbet,maxbet,maxodds,forfeitblocks; struct CCcontract_info *cp,C;
if ( bet < 0 || odds < 1 )
{
fprintf(stderr,"negative parameter error\n");
return(0);
}
cp = CCinit(&C,EVAL_DICE);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
dicepk = GetUnspendable(cp,0);
sbits = stringbits(planstr);
if ( DicePlanExists(cp,sbits,dicepk,minbet,maxbet,maxodds,forfeitblocks) == 0 )
{
fprintf(stderr,"Dice plan %s doesnt exist\n",planstr);
return(0);
}
if ( bet < minbet )
{
fprintf(stderr,"Dice plan %s bet %.8f < minbet %.8f\n",planstr,(double)bet/COIN,(double)minbet/COIN);
return(0);
}
if ( (funding= DicePlanFunds(sbits,cp,dicepk,fundingtxid)) >= bet*odds+txfee )
{
if ( AddNormalinputs(mtx,mypk,bet+2*txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,bet,dicepk));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceOpRet('L',sbits,fundingtxid)));
} else fprintf(stderr,"cant find enough inputs %.8f note enough for %.8f\n",(double)funding/COIN,(double)bet/COIN);
}
fprintf(stderr,"cant find dice inputs\n");
return(0);
}
std::string DiceUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid)
{
CMutableTransaction mtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,dicepk; CScript opret,scriptPubKey,ignore; uint256 hashBlock; uint64_t funding,sbits,reward=0,amount=0,inputs,CCchange=0; int64_t minbet,maxbet,maxodds,forfeitblocks; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_DICE);
if ( txfee == 0 )
txfee = 10000;
dicepk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
sbits = stringbits(planstr);
if ( DicePlanExists(cp,sbits,dicepk,minbet,maxbet,maxodds,forfeitblocks) == 0 )
{
fprintf(stderr,"Dice plan %s doesnt exist\n",planstr);
return(0);
}
// need to deal with finding the right utxos
if ( locktxid == zeroid )
amount = AddDiceInputs(scriptPubKey,0,cp,mtx,dicepk,(1LL << 30),1);
else
{
GetCCaddress(cp,coinaddr,dicepk);
if ( (amount= CCutxovalue(coinaddr,locktxid,0)) == 0 )
{
fprintf(stderr,"%s locktxid/v0 is spent\n",coinaddr);
return(0);
}
if ( GetTransaction(locktxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
scriptPubKey = tx.vout[1].scriptPubKey;
mtx.vin.push_back(CTxIn(locktxid,0,CScript()));
}
else
{
fprintf(stderr,"%s no normal vout.1 in locktxid\n",coinaddr);
return(0);
}
}
if ( amount > 0 && (reward= DiceCalc(amount,mtx.vin[0].prevout.hash,minbet,maxbet,maxodds,forfeitblocks)) > txfee && scriptPubKey.size() > 0 )
{
if ( (inputs= AddDiceInputs(ignore,1,cp,mtx,dicepk,reward+txfee,30)) > 0 )
{
if ( inputs >= (reward + 2*txfee) )
CCchange = (inputs - (reward + txfee));
fprintf(stderr,"inputs %.8f CCchange %.8f amount %.8f reward %.8f\n",(double)inputs/COIN,(double)CCchange/COIN,(double)amount/COIN,(double)reward/COIN);
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dicepk));
mtx.vout.push_back(CTxOut(amount+reward,scriptPubKey));
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,EncodeDiceOpRet('U',sbits,fundingtxid)));
}
fprintf(stderr,"cant find enough dice inputs\n");
}
fprintf(stderr,"amount %.8f -> reward %.8f\n",(double)amount/COIN,(double)reward/COIN);
return(0);
}

View File

@@ -1,84 +0,0 @@
#include <cryptoconditions.h>
#include "hash.h"
#include "chain.h"
#include "version.h"
#include "script/cc.h"
#include "cc/eval.h"
#include "cc/betprotocol.h"
#include "primitives/transaction.h"
/*
* Crypto-Condition EVAL method that resolves a dispute of a session
*
* IN: vm - AppVM virtual machine to verify states
* IN: params - condition params
* IN: disputeTx - transaction attempting to resolve dispute
* IN: nIn - index of input of dispute tx
*
* disputeTx: attempt to resolve a dispute
*
* in 0: Spends Session TX first output, reveals DisputeHeader
* out 0: OP_RETURN hash of payouts
*/
bool Eval::DisputePayout(AppVM &vm, std::vector<uint8_t> params, const CTransaction &disputeTx, unsigned int nIn)
{
if (disputeTx.vout.size() == 0) return Invalid("no-vouts");
// get payouts hash
uint256 payoutHash;
if (!GetOpReturnHash(disputeTx.vout[0].scriptPubKey, payoutHash))
return Invalid("invalid-payout-hash");
// load params
uint16_t waitBlocks;
std::vector<uint8_t> vmParams;
if (!E_UNMARSHAL(params, ss >> VARINT(waitBlocks); ss >> vmParams))
return Invalid("malformed-params");
// ensure that enough time has passed
{
CTransaction sessionTx;
CBlockIndex sessionBlock;
// if unconformed its too soon
if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock))
return Error("couldnt-get-parent");
if (GetCurrentHeight() < sessionBlock.nHeight + waitBlocks)
return Invalid("dispute-too-soon"); // Not yet
}
// get spends
std::vector<CTransaction> spends;
if (!GetSpendsConfirmed(disputeTx.vin[0].prevout.hash, spends))
return Error("couldnt-get-spends");
// verify result from VM
int maxLength = -1;
uint256 bestPayout;
for (int i=1; i<spends.size(); i++)
{
std::vector<unsigned char> vmState;
if (spends[i].vout.size() == 0) continue;
if (!GetOpReturnData(spends[i].vout[0].scriptPubKey, vmState)) continue;
auto out = vm.evaluate(vmParams, vmState);
uint256 resultHash = SerializeHash(out.second);
if (out.first > maxLength) {
maxLength = out.first;
bestPayout = resultHash;
}
// The below means that if for any reason there is a draw, the first dispute wins
else if (out.first == maxLength) {
if (bestPayout != payoutHash) {
fprintf(stderr, "WARNING: VM has multiple solutions of same length\n");
bestPayout = resultHash;
}
}
}
if (maxLength == -1) return Invalid("no-evidence");
return bestPayout == payoutHash ? Valid() : Invalid("wrong-payout");
}

View File

@@ -1,24 +1,44 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include <assert.h>
#include <cryptoconditions.h>
#include "primitives/block.h"
#include "primitives/transaction.h"
#include "script/cc.h"
#include "cc/eval.h"
#include "cc/utils.h"
#include "cc/CCinclude.h"
#include "main.h"
#include "chain.h"
#include "core_io.h"
#include "crosschain.h"
Eval* EVAL_TEST = 0;
struct CCcontract_info CCinfos[0x100];
bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
{
Eval eval_;
Eval *eval = EVAL_TEST;
if (!eval) eval = &eval_;
// DISABLE CRYPTO CONDITIONS FOR NOW
return false;
EvalRef eval;
bool out = eval->Dispatch(cond, tx, nIn);
//fprintf(stderr,"out %d vs %d isValid\n",(int32_t)out,(int32_t)eval->state.IsValid());
assert(eval->state.IsValid() == out);
if (eval->state.IsValid()) return true;
@@ -39,17 +59,33 @@ bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
*/
bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
{
struct CCcontract_info *cp;
if (cond->codeLength == 0)
return Invalid("empty-eval");
uint8_t ecode = cond->code[0];
std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
if (ecode == EVAL_IMPORTPAYOUT) {
return ImportPayout(vparams, txTo, nIn);
cp = &CCinfos[(int32_t)ecode];
if ( cp->didinit == 0 )
{
CCinit(cp,ecode);
cp->didinit = 1;
}
return Invalid("invalid-code");
std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
switch ( ecode )
{
case EVAL_IMPORTPAYOUT:
return ImportPayout(vparams, txTo, nIn);
break;
case EVAL_IMPORTCOIN:
return ImportCoin(vparams, txTo, nIn);
break;
default:
return(ProcessCC(cp,this, vparams, txTo, nIn));
break;
}
return Invalid("invalid-code, dont forget to add EVAL_NEWCC to Eval::Dispatch");
}
@@ -62,8 +98,11 @@ bool Eval::GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) c
bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const
{
bool fAllowSlow = false; // Don't allow slow
return GetTransaction(hash, txOut, hashBlock, fAllowSlow);
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
// there is a LOCK(cs_main) in the normal GetTransaction(), which leads to deadlocks
//bool fAllowSlow = false; // Don't allow slow
//return GetTransaction(hash, txOut, hashBlock, fAllowSlow);
return myGetTransaction(hash, txOut,hashBlock);
}
@@ -83,7 +122,6 @@ unsigned int Eval::GetCurrentHeight() const
return chainActive.Height();
}
bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const
{
auto r = mapBlockIndex.find(hash);
@@ -95,7 +133,6 @@ bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const
return false;
}
extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
@@ -144,7 +181,7 @@ bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t t
/*
* Get MoM from a notarisation tx hash
* Get MoM from a notarisation tx hash (on KMD)
*/
bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data) const
{
@@ -152,54 +189,84 @@ bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data)
CBlockIndex block;
if (!GetTxConfirmed(notaryHash, notarisationTx, block)) return false;
if (!CheckNotaryInputs(notarisationTx, block.nHeight, block.nTime)) return false;
if (notarisationTx.vout.size() < 2) return false;
if (!data.Parse(notarisationTx.vout[1].scriptPubKey)) return false;
if (!ParseNotarisationOpReturn(notarisationTx, data)) return false;
return true;
}
/*
* Get MoMoM corresponding to a notarisation tx hash (on assetchain)
*/
bool Eval::GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const
{
std::pair<uint256,NotarisationData> out;
if (!GetNextBacknotarisation(kmdNotarisationHash, out)) return false;
momom = out.second.MoMoM;
return true;
}
uint32_t Eval::GetAssetchainsCC() const
{
return ASSETCHAINS_CC;
}
std::string Eval::GetAssetchainsSymbol() const
{
return std::string(ASSETCHAINS_SYMBOL);
}
/*
* Notarisation data, ie, OP_RETURN payload in notarisation transactions
*/
extern char ASSETCHAINS_SYMBOL[16];
bool NotarisationData::Parse(const CScript scriptPK)
bool ParseNotarisationOpReturn(const CTransaction &tx, NotarisationData &data)
{
*this = NotarisationData();
if (tx.vout.size() < 2) return false;
std::vector<unsigned char> vdata;
if (!GetOpReturnData(scriptPK, vdata)) return false;
CDataStream ss(vdata, SER_NETWORK, PROTOCOL_VERSION);
try {
ss >> blockHash;
ss >> height;
if (ASSETCHAINS_SYMBOL[0])
ss >> txHash;
char *nullPos = (char*) memchr(&ss[0], 0, ss.size());
if (!nullPos) return false;
ss.read(symbol, nullPos-&ss[0]+1);
if (ss.size() < 36) return false;
ss >> MoM;
ss >> MoMDepth;
} catch (...) {
return false;
}
return true;
if (!GetOpReturnData(tx.vout[1].scriptPubKey, vdata)) return false;
bool out = E_UNMARSHAL(vdata, ss >> data);
return out;
}
/*
* Misc
*/
std::string EvalToStr(EvalCode c)
{
FOREACH_EVAL(EVAL_GENERATE_STRING);
char s[10];
sprintf(s, "0x%x", c);
return std::string(s);
}
uint256 SafeCheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
if (nIndex == -1)
return uint256();
for (auto it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
{
if (nIndex & 1) {
if (*it == hash) {
// non canonical. hash may be equal to node but never on the right.
return uint256();
}
hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
}
else
hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
nIndex >>= 1;
}
return hash;
}
uint256 GetMerkleRoot(const std::vector<uint256>& vLeaves)
{
bool fMutated;
std::vector<uint256> vMerkleTree;
return BuildMerkleTree(&fMutated, vLeaves, vMerkleTree);
}

View File

@@ -1,14 +1,31 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_EVAL_H
#define CC_EVAL_H
#include <cryptoconditions.h>
#include "cc/utils.h"
#include "chain.h"
#include "streams.h"
#include "version.h"
#include "consensus/validation.h"
#include "primitives/transaction.h"
#define KOMODO_FIRSTFUNGIBLEID 100
/*
* Eval codes
@@ -20,8 +37,17 @@
* a possible code is EVAL_BITCOIN_SCRIPT, where the entire binary
* after the code is interpreted as a bitcoin script.
*/
#define FOREACH_EVAL(EVAL) \
EVAL(EVAL_IMPORTPAYOUT, 0xe1)
#define FOREACH_EVAL(EVAL) \
EVAL(EVAL_IMPORTPAYOUT, 0xe1) \
EVAL(EVAL_IMPORTCOIN, 0xe2) \
EVAL(EVAL_ASSETS, 0xe3) \
EVAL(EVAL_FAUCET, 0xe4) \
EVAL(EVAL_REWARDS, 0xe5) \
EVAL(EVAL_DICE, 0xe6) \
EVAL(EVAL_PONZI, 0xe7) \
EVAL(EVAL_AUCTION, 0xe8) \
EVAL(EVAL_LOTTO, 0xe9)
typedef uint8_t EvalCode;
@@ -54,6 +80,11 @@ public:
*/
bool ImportPayout(std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn);
/*
* Import coin from another chain with same symbol
*/
bool ImportCoin(std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn);
/*
* IO functions
*/
@@ -64,10 +95,30 @@ public:
virtual bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const;
virtual int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const;
virtual bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const;
virtual bool GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const;
virtual bool CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const;
virtual uint32_t GetAssetchainsCC() const;
virtual std::string GetAssetchainsSymbol() const;
};
extern Eval* EVAL_TEST;
/*
* Get a pointer to an Eval to use
*/
typedef std::unique_ptr<Eval,void(*)(Eval*)> EvalRef_;
class EvalRef : public EvalRef_
{
public:
EvalRef() : EvalRef_(
EVAL_TEST ? EVAL_TEST : new Eval(),
[](Eval* e){if (e!=EVAL_TEST) delete e;}) { }
};
bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn);
@@ -88,22 +139,92 @@ public:
};
/*
* Data from notarisation OP_RETURN
*/
class NotarisationData {
public:
uint256 blockHash;
uint32_t height;
uint256 txHash; // Only get this guy in asset chains not in KMD
char symbol[64];
uint256 MoM;
uint32_t MoMDepth;
extern char ASSETCHAINS_SYMBOL[65];
bool Parse(CScript scriptPubKey);
/*
* Data from notarisation OP_RETURN from chain being notarised
*/
class NotarisationData
{
public:
int IsBackNotarisation = 0;
uint256 blockHash = uint256();
uint32_t height = 0;
uint256 txHash = uint256();
char symbol[64];
uint256 MoM = uint256();
uint16_t MoMDepth = 0;
uint16_t ccId = 0;
uint256 MoMoM = uint256();
uint32_t MoMoMDepth = 0;
NotarisationData(int IsBack=2) : IsBackNotarisation(IsBack) {
symbol[0] = '\0';
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
bool IsBack = IsBackNotarisation;
if (2 == IsBackNotarisation) IsBack = DetectBackNotarisation(s, ser_action);
READWRITE(blockHash);
READWRITE(height);
if (IsBack)
READWRITE(txHash);
SerSymbol(s, ser_action);
if (s.size() == 0) return;
READWRITE(MoM);
READWRITE(MoMDepth);
READWRITE(ccId);
if (s.size() == 0) return;
if (IsBack) {
READWRITE(MoMoM);
READWRITE(MoMoMDepth);
}
}
template <typename Stream>
void SerSymbol(Stream& s, CSerActionSerialize act)
{
s.write(symbol, strlen(symbol)+1);
}
template <typename Stream>
void SerSymbol(Stream& s, CSerActionUnserialize act)
{
size_t readlen = std::min(sizeof(symbol), s.size());
char *nullPos = (char*) memchr(&s[0], 0, readlen);
if (!nullPos)
throw std::ios_base::failure("couldn't parse symbol");
s.read(symbol, nullPos-&s[0]+1);
}
template <typename Stream>
bool DetectBackNotarisation(Stream& s, CSerActionUnserialize act)
{
if (ASSETCHAINS_SYMBOL[0]) return 1;
if (s.size() >= 72) {
if (strcmp("BTC", &s[68]) == 0) return 1;
if (strcmp("KMD", &s[68]) == 0) return 1;
}
return 0;
}
template <typename Stream>
bool DetectBackNotarisation(Stream& s, CSerActionSerialize act)
{
return !txHash.IsNull();
}
};
bool ParseNotarisationOpReturn(const CTransaction &tx, NotarisationData &data);
/*
* Eval code utilities.
*/
@@ -116,28 +237,44 @@ std::string EvalToStr(EvalCode c);
/*
* Serialisation boilerplate
* Merkle stuff
*/
#define E_MARSHAL(body) SerializeF([&] (CDataStream &ss) {body;})
template <class T>
std::vector<uint8_t> SerializeF(const T f)
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
f(ss);
return std::vector<unsigned char>(ss.begin(), ss.end());
}
uint256 SafeCheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
#define E_UNMARSHAL(params, body) DeserializeF(params, [&] (CDataStream &ss) {body;})
template <class T>
bool DeserializeF(const std::vector<unsigned char> vIn, T f)
class MerkleBranch
{
CDataStream ss(vIn, SER_NETWORK, PROTOCOL_VERSION);
try {
f(ss);
if (ss.eof()) return true;
} catch(...) {}
return false;
}
public:
int nIndex;
std::vector<uint256> branch;
MerkleBranch() {}
MerkleBranch(int i, std::vector<uint256> b) : nIndex(i), branch(b) {}
uint256 Exec(uint256 hash) const { return SafeCheckMerkleBranch(hash, branch, nIndex); }
MerkleBranch& operator<<(MerkleBranch append)
{
nIndex += append.nIndex << branch.size();
branch.insert(branch.end(), append.branch.begin(), append.branch.end());
return *this;
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(VARINT(nIndex));
READWRITE(branch);
}
};
typedef std::pair<uint256,MerkleBranch> TxProof;
uint256 GetMerkleRoot(const std::vector<uint256>& vLeaves);
struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode);
bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull, const CTransaction &tx, unsigned int nIn);
#endif /* CC_EVAL_H */

190
src/cc/faucet.cpp Normal file
View File

@@ -0,0 +1,190 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCfaucet.h"
#include "../txmempool.h"
/*
This file implements a simple CC faucet as an example of how to make a new CC contract. It wont have any fancy sybil protection but will serve the purpose of a fully automated faucet.
In order to implement a faucet, we need to have it funded. Once it is funded, anybody should be able to get some reasonable small amount.
This leads to needing to lock the funding in a CC protected output. And to put a spending limit. We can do a per transaction spending limit quite easily with vout constraints. However, that would allow anybody to issue thousands of transactions per block, so we also need to add a rate limiter.
To implement this, we can simply make any faucet vout fund the faucet. Then we can limit the number of confirmed utxo by combining faucet outputs and then only using utxo which are confirmed. This combined with a vout size limit will drastically limit the funds that can be withdrawn from the faucet.
*/
// start of consensus code
uint64_t IsFaucetvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
//fprintf(stderr,"vini.%d\n",i);
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
//fprintf(stderr,"vini.%d check mempool\n",i);
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("cant find vinTx");
else
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant faucet from mempool");
if ( (assetoshis= IsFaucetvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsFaucetvout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+COIN+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + COIN + txfee");
}
else return(true);
}
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
{
//fprintf(stderr,"check vins\n");
for (i=0; i<numvins; i++)
{
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
{
fprintf(stderr,"faucetget invalid vini\n");
return eval->Invalid("illegal normal vini");
}
}
//fprintf(stderr,"check amounts\n");
if ( FaucetExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"faucetget invalid amount\n");
return false;
}
else
{
preventCCvouts = 1;
if ( IsFaucetvout(cp,tx,0) != 0 )
{
preventCCvouts++;
i = 1;
} else i = 0;
if ( tx.vout[i].nValue != COIN )
return eval->Invalid("invalid faucet output");
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"faucetget validated\n");
else fprintf(stderr,"faucetget invalid\n");
return(retval);
}
}
}
// end of consensus code
// helper functions for rpc calls in rpcwallet.cpp
uint64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
{
char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
// prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsFaucetvout(cp,vintx,(int32_t)it->first.index)) > 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
}
}
}
return(totalinputs);
}
std::string FaucetGet(uint64_t txfee)
{
CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_FAUCET);
if ( txfee == 0 )
txfee = 10000;
faucetpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddFaucetInputs(cp,mtx,faucetpk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,CCchange,faucetpk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
} else fprintf(stderr,"cant find faucet inputs\n");
return(0);
}
std::string FaucetFund(uint64_t txfee,uint64_t funds)
{
CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_FAUCET);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
faucetpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,funds,faucetpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
return(0);
}

90
src/cc/import.cpp Normal file
View File

@@ -0,0 +1,90 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "cc/eval.h"
#include "cc/utils.h"
#include "importcoin.h"
#include "primitives/transaction.h"
/*
* CC Eval method for import coin.
*
* This method should control every parameter of the ImportCoin transaction, since it has no signature
* to protect it from malleability.
*/
bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn)
{
if (importTx.vout.size() < 2)
return Invalid("too-few-vouts");
// params
TxProof proof;
CTransaction burnTx;
std::vector<CTxOut> payouts;
if (!UnmarshalImportTx(importTx, proof, burnTx, payouts))
return Invalid("invalid-params");
// Control all aspects of this transaction
// It should not be at all malleable
if (MakeImportCoinTransaction(proof, burnTx, payouts).GetHash() != importTx.GetHash())
return Invalid("non-canonical");
// burn params
uint32_t targetCcid;
std::string targetSymbol;
uint256 payoutsHash;
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash))
return Invalid("invalid-burn-tx");
if (targetCcid != GetAssetchainsCC() || targetSymbol != GetAssetchainsSymbol())
return Invalid("importcoin-wrong-chain");
if (targetCcid < KOMODO_FIRSTFUNGIBLEID)
return Invalid("chain-not-fungible");
// check burn amount
{
uint64_t burnAmount = burnTx.vout[0].nValue;
if (burnAmount == 0)
return Invalid("invalid-burn-amount");
uint64_t totalOut = 0;
for (int i=0; i<importTx.vout.size(); i++)
totalOut += importTx.vout[i].nValue;
if (totalOut > burnAmount)
return Invalid("payout-too-high");
}
// Check burntx shows correct outputs hash
if (payoutsHash != SerializeHash(payouts))
return Invalid("wrong-payouts");
// Check proof confirms existance of burnTx
{
uint256 momom, target;
if (!GetProofRoot(proof.first, momom))
return Invalid("coudnt-load-momom");
target = proof.second.Exec(burnTx.GetHash());
if (momom != proof.second.Exec(burnTx.GetHash()))
return Invalid("momom-check-fail");
}
return Valid();
}

View File

@@ -1,76 +0,0 @@
#include <cryptoconditions.h>
#include "main.h"
#include "chain.h"
#include "streams.h"
#include "cc/eval.h"
#include "cc/betprotocol.h"
#include "primitives/transaction.h"
/*
* Crypto-Condition EVAL method that verifies a payout against a transaction
* notarised on another chain.
*
* IN: params - condition params
* IN: importTx - Payout transaction on value chain (KMD)
* IN: nIn - index of input of stake
*
* importTx: Spends stakeTx with payouts from asset chain
*
* in 0: Spends Stake TX and contains ImportPayout CC
* out 0: OP_RETURN MomProof, disputeTx
* out 1-: arbitrary payouts
*
* disputeTx: Spends sessionTx.0 (opener on asset chain)
*
* in 0: spends sessionTx.0
* in 1-: anything
* out 0: OP_RETURN hash of payouts
* out 1-: anything
*/
bool Eval::ImportPayout(const std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn)
{
if (importTx.vout.size() == 0) return Invalid("no-vouts");
// load data from vout[0]
MoMProof proof;
CTransaction disputeTx;
{
std::vector<unsigned char> vopret;
GetOpReturnData(importTx.vout[0].scriptPubKey, vopret);
if (!E_UNMARSHAL(vopret, ss >> proof; ss >> disputeTx))
return Invalid("invalid-payload");
}
// Check disputeTx.0 shows correct payouts
{
uint256 givenPayoutsHash;
GetOpReturnHash(disputeTx.vout[0].scriptPubKey, givenPayoutsHash);
std::vector<CTxOut> payouts(importTx.vout.begin() + 1, importTx.vout.end());
if (givenPayoutsHash != SerializeHash(payouts))
return Invalid("wrong-payouts");
}
// Check disputeTx spends sessionTx.0
// condition ImportPayout params is session ID from other chain
{
uint256 sessionHash;
if (!E_UNMARSHAL(params, ss >> sessionHash))
return Invalid("malformed-params");
if (disputeTx.vin[0].prevout != COutPoint(sessionHash, 0))
return Invalid("wrong-session");
}
// Check disputeTx solves momproof from vout[0]
{
NotarisationData data;
if (!GetNotarisationData(proof.notarisationHash, data))
return Invalid("coudnt-load-mom");
if (data.MoM != proof.Exec(disputeTx.GetHash()))
return Invalid("mom-check-fail");
}
return Valid();
}

183
src/cc/lotto.cpp Normal file
View File

@@ -0,0 +1,183 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CClotto.h"
#include "../txmempool.h"
/*
*/
// start of consensus code
uint64_t IsLottovout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
bool LottoExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
//fprintf(stderr,"vini.%d\n",i);
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
//fprintf(stderr,"vini.%d check mempool\n",i);
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("cant find vinTx");
else
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant Lotto from mempool");
if ( (assetoshis= IsLottovout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsLottovout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+COIN+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + COIN + txfee");
}
else return(true);
}
bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
{
//fprintf(stderr,"check vins\n");
for (i=0; i<numvins; i++)
{
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
{
fprintf(stderr,"Lottoget invalid vini\n");
return eval->Invalid("illegal normal vini");
}
}
//fprintf(stderr,"check amounts\n");
if ( LottoExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"Lottoget invalid amount\n");
return false;
}
else
{
preventCCvouts = 1;
if ( IsLottovout(cp,tx,0) != 0 )
{
preventCCvouts++;
i = 1;
} else i = 0;
if ( tx.vout[i].nValue != COIN )
return eval->Invalid("invalid Lotto output");
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"Lottoget validated\n");
else fprintf(stderr,"Lottoget invalid\n");
return(retval);
}
}
}
// end of consensus code
// helper functions for rpc calls in rpcwallet.cpp
uint64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
{
char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
// prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsLottovout(cp,vintx,(int32_t)it->first.index)) > 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
}
}
}
return(totalinputs);
}
std::string LottoTicket(uint64_t txfee,uint64_t numtickets)
{
CMutableTransaction mtx; CPubKey mypk,Lottopk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_LOTTO);
if ( txfee == 0 )
txfee = 10000;
Lottopk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddLottoInputs(cp,mtx,Lottopk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,CCchange,Lottopk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
} else fprintf(stderr,"cant find Lotto inputs\n");
return(0);
}
std::string LottoWinner(uint64_t txfee)
{
CMutableTransaction mtx; CPubKey mypk,Lottopk; uint64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_LOTTO);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
Lottopk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,winnings,Lottopk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
return(0);
}

183
src/cc/ponzi.cpp Normal file
View File

@@ -0,0 +1,183 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCponzi.h"
#include "../txmempool.h"
/*
*/
// start of consensus code
uint64_t IsPonzivout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
bool PonziExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
//fprintf(stderr,"vini.%d\n",i);
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
//fprintf(stderr,"vini.%d check mempool\n",i);
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("cant find vinTx");
else
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant ponzi from mempool");
if ( (assetoshis= IsPonzivout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsPonzivout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+COIN+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + COIN + txfee");
}
else return(true);
}
bool PonziValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
{
//fprintf(stderr,"check vins\n");
for (i=0; i<numvins; i++)
{
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
{
fprintf(stderr,"ponziget invalid vini\n");
return eval->Invalid("illegal normal vini");
}
}
//fprintf(stderr,"check amounts\n");
if ( PonziExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"ponziget invalid amount\n");
return false;
}
else
{
preventCCvouts = 1;
if ( IsPonzivout(cp,tx,0) != 0 )
{
preventCCvouts++;
i = 1;
} else i = 0;
if ( tx.vout[i].nValue != COIN )
return eval->Invalid("invalid ponzi output");
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"ponziget validated\n");
else fprintf(stderr,"ponziget invalid\n");
return(retval);
}
}
}
// end of consensus code
// helper functions for rpc calls in rpcwallet.cpp
uint64_t AddPonziInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
{
char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
// prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsPonzivout(cp,vintx,(int32_t)it->first.index)) > 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
}
}
}
return(totalinputs);
}
std::string PonziBuy(uint64_t txfee,uint64_t amount)
{
CMutableTransaction mtx; CPubKey mypk,ponzipk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_PONZI);
if ( txfee == 0 )
txfee = 10000;
ponzipk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddPonziInputs(cp,mtx,ponzipk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_PONZI,CCchange,ponzipk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
} else fprintf(stderr,"cant find ponzi inputs\n");
return(0);
}
std::string PonziClaim(uint64_t txfee)
{
CMutableTransaction mtx; CPubKey mypk,ponzipk; uint64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_PONZI);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
ponzipk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_PONZI,funds,ponzipk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
return(0);
}

553
src/cc/rewards.cpp Normal file
View File

@@ -0,0 +1,553 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "CCinclude.h"
/*
The rewards CC contract is initially for OOT, which needs this functionality. However, many of the attributes can be parameterized to allow different rewards programs to run. Multiple rewards plans could even run on the same blockchain, though the user would need to choose which one to lock funds into.
At the high level, the user would lock funds for some amount of time and at the end of it, would get all the locked funds back with an additional reward. So there needs to be a lock funds and unlock funds ability. Additionally, the rewards need to come from somewhere, so similar to the faucet, there would be a way to fund the reward.
Additional requirements are for the user to be able to lock funds via SPV. This requirement in turns forces the creation of a way for anybody to be able to unlock the funds as that operation requires a native daemon running and cant be done over SPV. The idea is to allow anybody to run a script that would unlock all funds that are matured. As far as the user is concerned, he locks his funds via SPV and after some time it comes back with an extra reward.
In reality, the funds are locked into a CC address that is unspendable, except for some special conditions and it needs to come back to the address that funded the lock. In order to implement this, several things are clear.
1) each locked CC utxo needs to be linked to a specific rewards plan
2) each locked CC utxo needs to know the only address that it can be unlocked into
3) SPV requirement means the lock transaction needs to be able to be created without any CC signing
The opreturn will be used to store the name of the rewards plan and all funding and locked funds with the same plan will use the same pool of rewards. plan names will be limited to 8 chars and encoded into a uint64_t.
The initial funding transaction will have all the parameters for the rewards plan encoded in the vouts. Additional fundings will just increase the available CC utxo for the rewards.
Locks wont have any CC vins, but will send to the RewardsCCaddress, with the plan stringbits in the opreturn. vout1 will have the unlock address and no other destination is valid.
Unlock does a CC spend to the vout1 address
createfunding
vins.*: normal inputs
vout.0: CC vout for funding
vout.1: normal marker vout for easy searching
vout.2: normal change
vout.n-1: opreturn 'F' sbits APR minseconds maxseconds mindeposit
addfunding
vins.*: normal inputs
vout.0: CC vout for funding
vout.1: normal change
vout.n-1: opreturn 'A' sbits fundingtxid
lock
vins.*: normal inputs
vout.0: CC vout for locked funds
vout.1: normal output to unlock address
vout.2: change
vout.n-1: opreturn 'L' sbits fundingtxid
unlock
vin.0: locked funds CC vout.0 from lock
vin.1+: funding CC vout.0 from 'F' and 'A' and 'U'
vout.0: funding CC change
vout.1: normal output to unlock address
vout.n-1: opreturn 'U' sbits fundingtxid
*/
uint64_t RewardsCalc(uint64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit)
{
uint64_t duration,reward = 0;
fprintf(stderr,"minseconds %llu maxseconds %llu\n",(long long)minseconds,(long long)maxseconds);
if ( (duration= CCduration(txid)) < minseconds )
{
return(0);
//duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24);
} else if ( duration > maxseconds )
duration = maxseconds;
reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100);
fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN);
return(reward);
}
CScript EncodeRewardsFundingOpRet(uint8_t funcid,uint64_t sbits,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit)
{
CScript opret; uint8_t evalcode = EVAL_REWARDS;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << sbits << APR << minseconds << maxseconds << mindeposit);
return(opret);
}
uint8_t DecodeRewardsFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,uint64_t &APR,uint64_t &minseconds,uint64_t &maxseconds,uint64_t &mindeposit)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> APR; ss >> minseconds; ss >> maxseconds; ss >> mindeposit) != 0 )
{
if ( e == EVAL_REWARDS && f == 'F' )
return(f);
}
return(0);
}
CScript EncodeRewardsOpRet(uint8_t funcid,uint64_t sbits,uint256 fundingtxid)
{
CScript opret; uint8_t evalcode = EVAL_REWARDS;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << sbits << fundingtxid);
return(opret);
}
uint8_t DecodeRewardsOpRet(uint256 txid,const CScript &scriptPubKey,uint64_t &sbits,uint256 &fundingtxid)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid; uint64_t APR,minseconds,maxseconds,mindeposit;
GetOpReturnData(scriptPubKey, vopret);
if ( vopret.size() > 2 )
{
script = (uint8_t *)vopret.data();
if ( script[0] == EVAL_REWARDS )
{
if ( script[1] == 'F' )
{
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> APR; ss >> minseconds; ss >> maxseconds; ss >> mindeposit) != 0 )
{
fundingtxid = txid;
return('F');
} else fprintf(stderr,"unmarshal error for F\n");
}
else if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> fundingtxid) != 0 )
{
if ( e == EVAL_REWARDS && (f == 'L' || f == 'U' || f == 'A') )
return(f);
else fprintf(stderr,"mismatched e.%02x f.(%c)\n",e,f);
}
} else fprintf(stderr,"script[0] %02x != EVAL_REWARDS\n",script[0]);
} else fprintf(stderr,"not enough opret.[%d]\n",(int32_t)vopret.size());
return(0);
}
uint64_t IsRewardsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("always should find vin, but didnt");
else
{
if ( hashBlock == zerohash )
return eval->Invalid("cant rewards from mempool");
if ( (assetoshis= IsRewardsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsRewardsvout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + txfee");
}
else return(true);
}
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
uint256 txid,fundingtxid,hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
{
txid = tx.GetHash();
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[numvouts-1].scriptPubKey,sbits,fundingtxid)) != 0 )
{
if ( eval->GetTxUnconfirmed(fundingtxid,fundingTx,hashBlock) == 0 )
return eval->Invalid("cant find fundingtxid");
else if ( fundingTx.vout.size() > 0 && DecodeRewardsFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 'F' )
return eval->Invalid("fundingTx not valid");
switch ( funcid )
{
case 'F':
//vins.*: normal inputs
//vout.0: CC vout for funding
//vout.1: normal marker vout for easy searching
//vout.2: normal change
//vout.n-1: opreturn 'F' sbits APR minseconds maxseconds mindeposit
return eval->Invalid("unexpected RewardsValidate for createfunding");
break;
case 'A':
//vins.*: normal inputs
//vout.0: CC vout for funding
//vout.1: normal change
//vout.n-1: opreturn 'A' sbits fundingtxid
return eval->Invalid("unexpected RewardsValidate for addfunding");
break;
case 'L':
//vins.*: normal inputs
//vout.0: CC vout for locked funds
//vout.1: normal output to unlock address
//vout.2: change
//vout.n-1: opreturn 'L' sbits fundingtxid
return eval->Invalid("unexpected RewardsValidate for lock");
break;
case 'U':
//vin.0: locked funds CC vout.0 from lock
//vin.1+: funding CC vout.0 from 'F' and 'A' and 'U'
//vout.0: funding CC change
//vout.1: normal output to unlock address
//vout.n-1: opreturn 'U' sbits fundingtxid
for (i=0; i<numvins; i++)
{
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) == 0 )
return eval->Invalid("unexpected normal vin for unlock");
}
if ( RewardsExactAmounts(cp,eval,tx,txfee+tx.vout[1].nValue) == 0 )
return false;
else if ( eval->GetTxUnconfirmed(tx.vin[0].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("always should find vin.0, but didnt");
else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
return eval->Invalid("lock tx vout.0 is normal output");
else if ( tx.vout.size() < 3 )
return eval->Invalid("unlock tx not enough vouts");
else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
return eval->Invalid("unlock tx vout.0 is normal output");
else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() != 0 )
return eval->Invalid("unlock tx vout.1 is CC output");
else if ( tx.vout[1].scriptPubKey != vinTx.vout[1].scriptPubKey )
return eval->Invalid("unlock tx vout.1 mismatched scriptPubKey");
amount = vinTx.vout[0].nValue;
reward = RewardsCalc(amount,tx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit);
if ( tx.vout[1].nValue > amount+reward )
return eval->Invalid("unlock tx vout.1 isnt amount+reward");
preventCCvouts = 1;
break;
}
}
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}
return(true);
}
// 'L' vs 'F' and 'A'
uint64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
{
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
fprintf(stderr,"(%s) %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;
if ( j != mtx.vin.size() )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
{
fprintf(stderr,"fundsflag.%d (%c) %.8f %.8f\n",fundsflag,funcid,(double)tx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN);
if ( fundsflag != 0 && funcid != 'F' && funcid != 'A' && funcid != 'U' )
continue;
else if ( fundsflag == 0 && (funcid != 'L' || tx.vout.size() < 4) )
continue;
if ( total != 0 && maxinputs != 0 )
{
if ( fundsflag == 0 )
scriptPubKey = tx.vout[1].scriptPubKey;
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
}
totalinputs += it->second.satoshis;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} else fprintf(stderr,"null funcid\n");
}
}
return(totalinputs);
}
uint64_t RewardsPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid)
{
char coinaddr[64]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
{
if ( (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid )
{
if ( refsbits == sbits && (nValue= IsRewardsvout(cp,tx,vout)) > 0 )
totalinputs += nValue;
else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN);
} //else fprintf(stderr,"else case\n");
} else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN);
}
}
return(totalinputs);
}
bool RewardsPlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey rewardspk,uint64_t &APR,uint64_t &minseconds,uint64_t &maxseconds,uint64_t &mindeposit)
{
char CCaddr[64]; uint64_t sbits; uint256 txid,hashBlock; CTransaction tx;
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
GetCCaddress(cp,CCaddr,rewardspk);
SetCCtxids(txids,CCaddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{
//int height = it->first.blockHeight;
txid = it->first.txhash;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 )
{
//char str[65]; fprintf(stderr,"rewards plan %s\n",uint256_str(str,txid));
if ( DecodeRewardsFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 'F' )
{
if ( sbits == refsbits )
return(true);
}
}
}
return(false);
}
UniValue RewardsInfo(uint256 rewardsid)
{
UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; uint64_t APR,minseconds,maxseconds,mindeposit,sbits; char str[67],numstr[65];
if ( GetTransaction(rewardsid,vintx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
result.push_back(Pair("error","cant find fundingtxid"));
return(result);
}
if ( vintx.vout.size() > 0 && DecodeRewardsFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 0 )
{
fprintf(stderr,"fundingtxid isnt rewards creation txid\n");
result.push_back(Pair("error","fundingtxid isnt rewards creation txid"));
return(result);
}
result.push_back(Pair("result","success"));
result.push_back(Pair("fundingtxid",uint256_str(str,rewardsid)));
unstringbits(str,sbits);
result.push_back(Pair("name",str));
result.push_back(Pair("sbits",sbits));
sprintf(numstr,"%.8f",(double)APR/COIN);
result.push_back(Pair("APR",numstr));
result.push_back(Pair("minseconds",minseconds));
result.push_back(Pair("maxseconds",maxseconds));
sprintf(numstr,"%.8f",(double)mindeposit/COIN);
result.push_back(Pair("mindeposit",numstr));
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN);
result.push_back(Pair("funding",numstr));
return(result);
}
UniValue RewardsList()
{
UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction vintx; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; char str[65];
cp = CCinit(&C,EVAL_REWARDS);
SetCCtxids(addressIndex,cp->normaladdr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeRewardsFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 0 )
{
result.push_back(uint256_str(str,txid));
}
}
}
return(result);
}
std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit)
{
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
if ( funds < 0 || mindeposit < 0 || minseconds < 0 || maxseconds < 0 )
{
fprintf(stderr,"negative parameter error\n");
return(0);
}
cp = CCinit(&C,EVAL_REWARDS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
rewardspk = GetUnspendable(cp,0);
sbits = stringbits(planstr);
if ( RewardsPlanExists(cp,sbits,rewardspk,a,b,c,d) != 0 )
{
fprintf(stderr,"Rewards plan (%s) already exists\n",planstr);
return(0);
}
if ( AddNormalinputs(mtx,mypk,funds+2*txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,rewardspk));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(rewardspk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsFundingOpRet('F',sbits,APR,minseconds,maxseconds,mindeposit)));
}
fprintf(stderr,"cant find enough inputs\n");
return(0);
}
std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
{
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
if ( amount < 0 )
{
fprintf(stderr,"negative parameter error\n");
return(0);
}
cp = CCinit(&C,EVAL_REWARDS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
rewardspk = GetUnspendable(cp,0);
sbits = stringbits(planstr);
if ( RewardsPlanExists(cp,sbits,rewardspk,a,b,c,d) == 0 )
{
fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr);
return(0);
}
sbits = stringbits(planstr);
if ( AddNormalinputs(mtx,mypk,amount+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,rewardspk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsOpRet('A',sbits,fundingtxid)));
} else fprintf(stderr,"cant find enough inputs\n");
fprintf(stderr,"cant find fundingtxid\n");
return(0);
}
std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t deposit)
{
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
if ( deposit < 0 )
{
fprintf(stderr,"negative parameter error\n");
return(0);
}
cp = CCinit(&C,EVAL_REWARDS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
rewardspk = GetUnspendable(cp,0);
sbits = stringbits(planstr);
if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 )
{
fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr);
return(0);
}
if ( deposit < mindeposit )
{
fprintf(stderr,"Rewards plan %s deposit %.8f < mindeposit %.8f\n",planstr,(double)deposit/COIN,(double)mindeposit/COIN);
return(0);
}
if ( (funding= RewardsPlanFunds(sbits,cp,rewardspk,fundingtxid)) >= deposit ) // arbitrary cmpval
{
if ( AddNormalinputs(mtx,mypk,deposit+2*txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,deposit,rewardspk));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsOpRet('L',sbits,fundingtxid)));
} else fprintf(stderr,"cant find enough inputs %.8f note enough for %.8f\n",(double)funding/COIN,(double)deposit/COIN);
}
fprintf(stderr,"cant find rewards inputs\n");
return(0);
}
std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid)
{
CMutableTransaction mtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript opret,scriptPubKey,ignore; uint256 hashBlock; uint64_t funding,sbits,reward=0,amount=0,inputs,CCchange=0,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_REWARDS);
if ( txfee == 0 )
txfee = 10000;
rewardspk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
sbits = stringbits(planstr);
if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 )
{
fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr);
return(0);
}
fprintf(stderr,"APR %.8f minseconds.%llu maxseconds.%llu mindeposit %.8f\n",(double)APR/COIN,(long long)minseconds,(long long)maxseconds,(double)mindeposit/COIN);
if ( locktxid == zeroid )
amount = AddRewardsInputs(scriptPubKey,0,cp,mtx,rewardspk,(1LL << 30),1);
else
{
GetCCaddress(cp,coinaddr,rewardspk);
if ( (amount= CCutxovalue(coinaddr,locktxid,0)) == 0 )
{
fprintf(stderr,"%s locktxid/v0 is spent\n",coinaddr);
return(0);
}
if ( GetTransaction(locktxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
scriptPubKey = tx.vout[1].scriptPubKey;
mtx.vin.push_back(CTxIn(locktxid,0,CScript()));
}
else
{
fprintf(stderr,"%s no normal vout.1 in locktxid\n",coinaddr);
return(0);
}
}
if ( amount > 0 && (reward= RewardsCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit)) > txfee && scriptPubKey.size() > 0 )
{
if ( (inputs= AddRewardsInputs(ignore,1,cp,mtx,rewardspk,reward+txfee,30)) > 0 )
{
if ( inputs >= (reward + 2*txfee) )
CCchange = (inputs - (reward + txfee));
fprintf(stderr,"inputs %.8f CCchange %.8f amount %.8f reward %.8f\n",(double)inputs/COIN,(double)CCchange/COIN,(double)amount/COIN,(double)reward/COIN);
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,rewardspk));
mtx.vout.push_back(CTxOut(amount+reward,scriptPubKey));
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid)));
}
fprintf(stderr,"cant find enough rewards inputs\n");
}
fprintf(stderr,"amount %.8f -> reward %.8f\n",(double)amount/COIN,(double)reward/COIN);
return(0);
}

0
src/cc/utils.cpp Normal file
View File

49
src/cc/utils.h Normal file
View File

@@ -0,0 +1,49 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef CC_UTILS_H
#define CC_UTILS_H
#include "streams.h"
#include "version.h"
/*
* Serialisation boilerplate
*/
template <class T>
std::vector<uint8_t> SerializeF(const T f)
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
f(ss);
return std::vector<unsigned char>(ss.begin(), ss.end());
}
template <class T>
bool DeserializeF(const std::vector<unsigned char> vIn, T f)
{
CDataStream ss(vIn, SER_NETWORK, PROTOCOL_VERSION);
try {
f(ss);
if (ss.eof()) return true;
} catch(...) {}
return false;
}
#define E_MARSHAL(body) SerializeF([&] (CDataStream &ss) {body;})
#define E_UNMARSHAL(params, body) DeserializeF(params, [&] (CDataStream &ss) {body;})
#endif /* CC_UTILS_H */

View File

@@ -121,7 +121,7 @@ public:
//! height of the entry in the chain. The genesis block has height 0
int nHeight;
int64_t newcoins,zfunds;
//! Which # file this block is stored in (blk?????.dat)
int nFile;
@@ -181,6 +181,7 @@ public:
void SetNull()
{
phashBlock = NULL;
newcoins = zfunds = 0;
pprev = NULL;
pskip = NULL;
nHeight = 0;
@@ -436,7 +437,7 @@ public:
CBlockIndex *Tip() const {
return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL;
}
/** Returns the last tip of the chain, or NULL if none. */
CBlockIndex *LastTip() const {
return vChain.size() > 0 ? lastTip : NULL;

View File

@@ -165,6 +165,7 @@ public:
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
vFixedSeeds.clear();
vSeeds.clear();
vSeeds.push_back(CDNSSeedData("veruscoin.io", "seeds.veruscoin.io")); // @kolo - old static dns seeds
vSeeds.push_back(CDNSSeedData("komodoplatform.com", "seeds.komodoplatform.com")); // @kolo - old static dns seeds
vSeeds.push_back(CDNSSeedData("kolo.supernet.org", "static.kolo.supernet.org")); // @kolo - new static dns seeds ToDo
vSeeds.push_back(CDNSSeedData("kolo.supernet.org", "dynamic.kolo.supernet.org")); // @kolo - crawler seeds ToDo
@@ -234,12 +235,6 @@ void *chainparams_commandline(void *ptr)
mainParams.pchMessageStart[3] = (ASSETCHAINS_MAGIC >> 24) & 0xff;
fprintf(stderr,">>>>>>>>>> %s: p2p.%u rpc.%u magic.%08x %u %u coins\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY);
// only require coinbase protection on Verus from the Komodo family of coins
if (strcmp(ASSETCHAINS_SYMBOL,"VRSC") == 0)
{
mainParams.consensus.fCoinbaseMustBeProtected = true;
}
if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH)
{
// this is only good for 60 second blocks with an averaging window of 45. for other parameters, use:
@@ -261,22 +256,38 @@ void *chainparams_commandline(void *ptr)
mainParams.consensus.nLwmaPOSAjustedWeight = 46531;
}
checkpointData = //(Checkpoints::CCheckpointData)
{
boost::assign::map_list_of
(0, mainParams.consensus.hashGenesisBlock)
(10000, uint256S("0xac2cd7d37177140ea4991cf630c0b9c7f94d707b84fb0351bf3a44856d2ae5dc"))
(20000, uint256S("0xb0e8cb9f77aaa7ff5bd90d6c08d06f4c4bf03e00c2b8a35a042e760845590c8a"))
(30000, uint256S("0xf2112ca577338ad7104bf905fa6a63d36b17a86f914c97b73cd31d43fcd7557c"))
(40000, uint256S("0x00000000008f83378dab727864b763ce91a4ea5f75d55939c0c1390cfb8c38f1"))
(49170, uint256S("0x2add646c0089871ec2379f02f7cd60b3af6efd9c152a6f16fc10925458c270cc")),
(int64_t)1529910234, // * UNIX timestamp of last checkpoint block
(int64_t)63661, // * total number of transactions between genesis and last checkpoint
// (the tx=... number in the SetBestChain debug.log lines)
(double)2777 // * estimated number of transactions per day after checkpoint
// total number of tx / (checkpoint block height / (24 * 24))
};
// only require coinbase protection on Verus from the Komodo family of coins
if (strcmp(ASSETCHAINS_SYMBOL,"VRSC") == 0)
{
mainParams.consensus.fCoinbaseMustBeProtected = true;
checkpointData = //(Checkpoints::CCheckpointData)
{
boost::assign::map_list_of
(0, mainParams.consensus.hashGenesisBlock)
(10000, uint256S("0xac2cd7d37177140ea4991cf630c0b9c7f94d707b84fb0351bf3a44856d2ae5dc"))
(20000, uint256S("0xb0e8cb9f77aaa7ff5bd90d6c08d06f4c4bf03e00c2b8a35a042e760845590c8a"))
(30000, uint256S("0xf2112ca577338ad7104bf905fa6a63d36b17a86f914c97b73cd31d43fcd7557c"))
(40000, uint256S("0x00000000008f83378dab727864b763ce91a4ea5f75d55939c0c1390cfb8c38f1"))
(49170, uint256S("0x2add646c0089871ec2379f02f7cd60b3af6efd9c152a6f16fc10925458c270cc")),
(int64_t)1529910234, // * UNIX timestamp of last checkpoint block
(int64_t)63661, // * total number of transactions between genesis and last checkpoint
// (the tx=... number in the SetBestChain debug.log lines)
(double)2777 // * estimated number of transactions per day after checkpoint
// total number of tx / (checkpoint block height / (24 * 24))
};
}
else
{
checkpointData = //(Checkpoints::CCheckpointData)
{
boost::assign::map_list_of
(0, mainParams.consensus.hashGenesisBlock),
(int64_t)1231006505,
(int64_t)1,
(double)2777 // * estimated number of transactions per day after checkpoint
// total number of tx / (checkpoint block height / (24 * 24))
};
}
}
else
{
@@ -572,11 +583,18 @@ public:
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K));
nEquihashN = N;
nEquihashK = K;
genesis.nTime = 1296688602;
genesis.nBits = KOMODO_MINDIFF_NBITS;
genesis.nNonce = uint256S("0x0000000000000000000000000000000000000000000000000000000000000021");
genesis.nSolution = ParseHex("0f2a976db4c4263da10fd5d38eb1790469cf19bdb4bf93450e09a72fdff17a3454326399");
genesis = CreateGenesisBlock(
1296688602,
uint256S("0x0000000000000000000000000000000000000000000000000000000000000009"),
ParseHex("01936b7db1eb4ac39f151b8704642d0a8bda13ec547d54cd5e43ba142fc6d8877cab07b3"),
KOMODO_MINDIFF_NBITS, 4, 0);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x029f11d80ef9765602235e1bc9727e3eb6ba20839319f761fee920d63401e327"));
assert(genesis.hashMerkleRoot == uint256S("0xc4eaa58879081de3c24a7b117ed2b28300e7ec4c4c1dff1d3f1268b7857a4ddb"));
nDefaultPort = 17779;
nPruneAfterHeight = 1000;

View File

@@ -8,6 +8,12 @@
* IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.
*/
static SeedSpec6 pnSeed6_main[] = {
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0xec}, 27485},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0xec}, 27487},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x40,0x69,0x6f}, 27485},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x40,0x69,0x6f}, 27487},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0x48}, 27485},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0x48}, 27487}
};
static SeedSpec6 pnSeed6_test[] = {

View File

@@ -9,6 +9,7 @@
#include "version.h"
#include "policy/fees.h"
#include "komodo_defs.h"
#include "importcoin.h"
#include <assert.h>
@@ -418,11 +419,13 @@ const CScript &CCoinsViewCache::GetSpendFor(const CTxIn& input) const
CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTransaction& tx,uint32_t tiptime) const
{
CAmount value,nResult = 0;
if ( interestp != 0 )
*interestp = 0;
if ( tx.IsCoinImport() )
return GetCoinImportValue(tx);
if ( tx.IsCoinBase() != 0 )
return 0;
CAmount value,nResult = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
value = GetOutputFor(tx.vin[i]).nValue;
@@ -447,6 +450,7 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr
return nResult;
}
bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const
{
boost::unordered_map<uint256, ZCIncrementalMerkleTree, CCoinsKeyHasher> intermediates;
@@ -483,12 +487,12 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const
bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
if (!tx.IsCoinBase()) {
if (!tx.IsMint()) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
const COutPoint &prevout = tx.vin[i].prevout;
const CCoins* coins = AccessCoins(prevout.hash);
if (!coins || !coins->IsAvailable(prevout.n)) {
fprintf(stderr,"HaveInputs missing input %s/v%d\n",prevout.hash.ToString().c_str(),prevout.n);
//fprintf(stderr,"HaveInputs missing input %s/v%d\n",prevout.hash.ToString().c_str(),prevout.n);
return false;
}
}
@@ -509,6 +513,9 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
if (tx.vjoinsplit.size() > 0) {
return MAX_PRIORITY;
}
if (tx.IsCoinImport()) {
return MAX_PRIORITY;
}
double dResult = 0.0;
BOOST_FOREACH(const CTxIn& txin, tx.vin)

336
src/crosschain.cpp Normal file
View File

@@ -0,0 +1,336 @@
#include "cc/eval.h"
#include "crosschain.h"
#include "importcoin.h"
#include "main.h"
#include "notarisationdb.h"
/*
* The crosschain workflow.
*
* 3 chains, A, B, and KMD. We would like to prove TX on B.
* There is a notarisation, nA0, which will include TX via an MoM.
* The notarisation nA0 must fall between 2 notarisations of B,
* ie, nB0 and nB1. An MoMoM including this range is propagated to
* B in notarisation receipt (backnotarisation) bnB2.
*
* A: TX bnA0
* \ /
* KMD: nB0 nA0 nB1 nB2
* \ \ \
* B: bnB0 bnB1 bnB2
*/
// XXX: There are potential crashes wherever we access chainActive without a lock,
// because it might be disconnecting blocks at the same time.
int NOTARISATION_SCAN_LIMIT_BLOCKS = 1440;
/* On KMD */
uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeight,
std::vector<uint256> &moms, uint256 &destNotarisationTxid)
{
/*
* Notaries don't wait for confirmation on KMD before performing a backnotarisation,
* but we need a determinable range that will encompass all merkle roots. Include MoMs
* including the block height of the last notarisation until the height before the
* previous notarisation.
*
* kmdHeight notarisations-0 notarisations-1
* *********************|
* > scan backwards >
*/
if (targetCCid < 2)
return uint256();
if (kmdHeight < 0 || kmdHeight > chainActive.Height())
return uint256();
int seenOwnNotarisations = 0;
for (int i=0; i<NOTARISATION_SCAN_LIMIT_BLOCKS; i++) {
if (i > kmdHeight) break;
NotarisationsInBlock notarisations;
uint256 blockHash = *chainActive[kmdHeight-i]->phashBlock;
if (!GetBlockNotarisations(blockHash, notarisations))
continue;
// See if we have an own notarisation in this block
BOOST_FOREACH(Notarisation& nota, notarisations) {
if (strcmp(nota.second.symbol, symbol) == 0)
{
seenOwnNotarisations++;
if (seenOwnNotarisations == 1)
destNotarisationTxid = nota.first;
else if (seenOwnNotarisations == 2)
goto end;
break;
}
}
if (seenOwnNotarisations == 1) {
BOOST_FOREACH(Notarisation& nota, notarisations) {
if (nota.second.ccId == targetCCid)
moms.push_back(nota.second.MoM);
}
}
}
end:
return GetMerkleRoot(moms);
}
/*
* Get a notarisation from a given height
*
* Will scan notarisations leveldb up to a limit
*/
template <typename IsTarget>
int ScanNotarisationsFromHeight(int nHeight, const IsTarget f, Notarisation &found)
{
int limit = std::min(nHeight + NOTARISATION_SCAN_LIMIT_BLOCKS, chainActive.Height());
for (int h=nHeight; h<limit; h++) {
NotarisationsInBlock notarisations;
if (!GetBlockNotarisations(*chainActive[h]->phashBlock, notarisations))
continue;
BOOST_FOREACH(found, notarisations) {
if (f(found)) {
return h;
}
}
}
return 0;
}
/* On KMD */
TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_t targetCCid,
const TxProof assetChainProof)
{
/*
* Here we are given a proof generated by an assetchain A which goes from given txid to
* an assetchain MoM. We need to go from the notarisationTxid for A to the MoMoM range of the
* backnotarisation for B (given by kmdheight of notarisation), find the MoM within the MoMs for
* that range, and finally extend the proof to lead to the MoMoM (proof root).
*/
EvalRef eval;
uint256 MoM = assetChainProof.second.Exec(txid);
// Get a kmd height for given notarisation Txid
int kmdHeight;
{
CTransaction sourceNotarisation;
uint256 hashBlock;
CBlockIndex blockIdx;
if (!eval->GetTxConfirmed(assetChainProof.first, sourceNotarisation, blockIdx))
throw std::runtime_error("Notarisation not found");
kmdHeight = blockIdx.nHeight;
}
// We now have a kmdHeight of the notarisation from chain A. So we know that a MoM exists
// at that height.
// If we call CalculateProofRoot with that height, it'll scan backwards, until it finds
// a notarisation from B, and it might not include our notarisation from A
// at all. So, the thing we need to do is scan forwards to find the notarisation for B,
// that is inclusive of A.
Notarisation nota;
auto isTarget = [&](Notarisation &nota) {
return strcmp(nota.second.symbol, targetSymbol) == 0;
};
kmdHeight = ScanNotarisationsFromHeight(kmdHeight, isTarget, nota);
if (!kmdHeight)
throw std::runtime_error("Cannot find notarisation for target inclusive of source");
// Get MoMs for kmd height and symbol
std::vector<uint256> moms;
uint256 targetChainNotarisationTxid;
uint256 MoMoM = CalculateProofRoot(targetSymbol, targetCCid, kmdHeight, moms, targetChainNotarisationTxid);
if (MoMoM.IsNull())
throw std::runtime_error("No MoMs found");
// Find index of source MoM in MoMoM
int nIndex;
for (nIndex=0; nIndex<moms.size(); nIndex++) {
if (moms[nIndex] == MoM)
goto cont;
}
throw std::runtime_error("Couldn't find MoM within MoMoM set");
cont:
// Create a branch
std::vector<uint256> vBranch;
{
CBlock fakeBlock;
for (int i=0; i<moms.size(); i++) {
CTransaction fakeTx;
// first value in CTransaction memory is it's hash
memcpy((void*)&fakeTx, moms[i].begin(), 32);
fakeBlock.vtx.push_back(fakeTx);
}
vBranch = fakeBlock.GetMerkleBranch(nIndex);
}
// Concatenate branches
MerkleBranch newBranch = assetChainProof.second;
newBranch << MerkleBranch(nIndex, vBranch);
// Check proof
if (newBranch.Exec(txid) != MoMoM)
throw std::runtime_error("Proof check failed");
return std::make_pair(targetChainNotarisationTxid,newBranch);
}
/*
* Takes an importTx that has proof leading to assetchain root
* and extends proof to cross chain root
*/
void CompleteImportTransaction(CTransaction &importTx)
{
TxProof proof;
CTransaction burnTx;
std::vector<CTxOut> payouts;
if (!UnmarshalImportTx(importTx, proof, burnTx, payouts))
throw std::runtime_error("Couldn't parse importTx");
std::string targetSymbol;
uint32_t targetCCid;
uint256 payoutsHash;
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCCid, payoutsHash))
throw std::runtime_error("Couldn't parse burnTx");
proof = GetCrossChainProof(burnTx.GetHash(), targetSymbol.data(), targetCCid, proof);
importTx = MakeImportCoinTransaction(proof, burnTx, payouts);
}
bool IsSameAssetChain(const Notarisation &nota) {
return strcmp(nota.second.symbol, ASSETCHAINS_SYMBOL) == 0;
};
/* On assetchain */
bool GetNextBacknotarisation(uint256 kmdNotarisationTxid, Notarisation &out)
{
/*
* Here we are given a txid, and a proof.
* We go from the KMD notarisation txid to the backnotarisation,
* then jump to the next backnotarisation, which contains the corresponding MoMoM.
*/
Notarisation bn;
if (!GetBackNotarisation(kmdNotarisationTxid, bn))
return false;
// Need to get block height of that backnotarisation
EvalRef eval;
CBlockIndex block;
CTransaction tx;
if (!eval->GetTxConfirmed(bn.first, tx, block)){
fprintf(stderr, "Can't get height of backnotarisation, this should not happen\n");
return false;
}
return (bool) ScanNotarisationsFromHeight(block.nHeight+1, &IsSameAssetChain, out);
}
/*
* On assetchain
* in: txid
* out: pair<notarisationTxHash,merkleBranch>
*/
TxProof GetAssetchainProof(uint256 hash)
{
int nIndex;
CBlockIndex* blockIndex;
Notarisation nota;
std::vector<uint256> branch;
{
uint256 blockHash;
CTransaction tx;
if (!GetTransaction(hash, tx, blockHash, true))
throw std::runtime_error("cannot find transaction");
if (blockHash.IsNull())
throw std::runtime_error("tx still in mempool");
blockIndex = mapBlockIndex[blockHash];
int h = blockIndex->nHeight;
// The assumption here is that the first notarisation for a height GTE than
// the transaction block height will contain the corresponding MoM. If there
// are sequence issues with the notarisations this may fail.
auto isTarget = [&](Notarisation &nota) {
if (!IsSameAssetChain(nota)) return false;
return nota.second.height >= blockIndex->nHeight;
};
if (!ScanNotarisationsFromHeight(blockIndex->nHeight, isTarget, nota))
throw std::runtime_error("backnotarisation not yet confirmed");
// index of block in MoM leaves
nIndex = nota.second.height - blockIndex->nHeight;
}
// build merkle chain from blocks to MoM
{
std::vector<uint256> leaves, tree;
for (int i=0; i<nota.second.MoMDepth; i++) {
uint256 mRoot = chainActive[nota.second.height - i]->hashMerkleRoot;
leaves.push_back(mRoot);
}
bool fMutated;
BuildMerkleTree(&fMutated, leaves, tree);
branch = GetMerkleBranch(nIndex, leaves.size(), tree);
// Check branch
uint256 ourResult = SafeCheckMerkleBranch(blockIndex->hashMerkleRoot, branch, nIndex);
if (nota.second.MoM != ourResult)
throw std::runtime_error("Failed merkle block->MoM");
}
// Now get the tx merkle branch
{
CBlock block;
if (fHavePruned && !(blockIndex->nStatus & BLOCK_HAVE_DATA) && blockIndex->nTx > 0)
throw std::runtime_error("Block not available (pruned data)");
if(!ReadBlockFromDisk(block, blockIndex,1))
throw std::runtime_error("Can't read block from disk");
// Locate the transaction in the block
int nTxIndex;
for (nTxIndex = 0; nTxIndex < (int)block.vtx.size(); nTxIndex++)
if (block.vtx[nTxIndex].GetHash() == hash)
break;
if (nTxIndex == (int)block.vtx.size())
throw std::runtime_error("Error locating tx in block");
std::vector<uint256> txBranch = block.GetMerkleBranch(nTxIndex);
// Check branch
if (block.hashMerkleRoot != CBlock::CheckMerkleBranch(hash, txBranch, nTxIndex))
throw std::runtime_error("Failed merkle tx->block");
// concatenate branches
nIndex = (nIndex << txBranch.size()) + nTxIndex;
branch.insert(branch.begin(), txBranch.begin(), txBranch.end());
}
// Check the proof
if (nota.second.MoM != CBlock::CheckMerkleBranch(hash, branch, nIndex))
throw std::runtime_error("Failed validating MoM");
// All done!
CDataStream ssProof(SER_NETWORK, PROTOCOL_VERSION);
return std::make_pair(nota.second.txHash, MerkleBranch(nIndex, branch));
}

21
src/crosschain.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef CROSSCHAIN_H
#define CROSSCHAIN_H
#include "cc/eval.h"
/* On assetchain */
TxProof GetAssetchainProof(uint256 hash);
/* On KMD */
uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeight,
std::vector<uint256> &moms, uint256 &destNotarisationTxid);
TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_t targetCCid,
const TxProof assetChainProof);
void CompleteImportTransaction(CTransaction &importTx);
/* On assetchain */
bool GetNextBacknotarisation(uint256 txid, std::pair<uint256,NotarisationData> &bn);
#endif /* CROSSCHAIN_H */

View File

@@ -14,11 +14,12 @@ bit output.
void (*CVerusHash::haraka512Function)(unsigned char *out, const unsigned char *in);
void CVerusHash::Hash(void *result, const void *data, size_t len)
void CVerusHash::Hash(void *result, const void *data, size_t _len)
{
unsigned char buf[128];
unsigned char *bufPtr = buf;
int pos = 0, nextOffset = 64;
int nextOffset = 64;
uint32_t pos = 0, len = _len;
unsigned char *bufPtr2 = bufPtr + nextOffset;
unsigned char *ptr = (unsigned char *)data;
@@ -58,14 +59,15 @@ void CVerusHash::init()
}
}
CVerusHash &CVerusHash::Write(const unsigned char *data, size_t len)
CVerusHash &CVerusHash::Write(const unsigned char *data, size_t _len)
{
unsigned char *tmp;
uint32_t pos, len = _len;
// digest up to 32 bytes at a time
for ( int pos = 0; pos < len; )
for ( pos = 0; pos < len; )
{
int room = 32 - curPos;
uint32_t room = 32 - curPos;
if (len - pos >= room)
{

View File

@@ -15,7 +15,7 @@ AM_CFLAGS = -I$(top_srcdir)/src/asn -I$(top_srcdir)/include -I$(top_srcdir)/src/
LIBSECP256K1=src/include/secp256k1/libsecp256k1.la
$(LIBSECP256K1): $(wildcard src/secp256k1/*)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) -march:x86-64 -g
CRYPTOCONDITIONS_CORE=libcryptoconditions_core.la

View File

@@ -1,3 +1,17 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "asn/Condition.h"
#include "asn/Fulfillment.h"

View File

@@ -1,3 +1,18 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "strings.h"
#include "asn/Condition.h"
#include "asn/Fulfillment.h"

View File

@@ -1,3 +1,18 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "asn/Condition.h"
#include "asn/Fulfillment.h"
#include "asn/Ed25519FingerprintContents.h"

View File

@@ -1,3 +1,18 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "asn/Condition.h"
#include "asn/Fulfillment.h"
#include "asn/EvalFulfillment.h"

View File

@@ -71,7 +71,7 @@ endif
endif
libsecp256k1_la_SOURCES = src/secp256k1.c
libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES)
libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -march=x86-64 -g
libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB)
libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c

View File

@@ -1,3 +1,18 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include <Condition.h>
#include <Fulfillment.h>
#include "include/cJSON.h"

View File

@@ -1,3 +1,18 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "cryptoconditions.h"
#include "internal.h"
#include <cJSON.h>

View File

@@ -1,3 +1,17 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "asn/Condition.h"
#include "asn/Fulfillment.h"

View File

@@ -1,3 +1,17 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "asn/Condition.h"
#include "asn/Fulfillment.h"

View File

@@ -1,3 +1,17 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "asn/Condition.h"
#include "asn/Fulfillment.h"

View File

@@ -1,3 +1,18 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

View File

@@ -6,11 +6,11 @@
#define ZCASH_DEPRECATION_H
// Deprecation policy:
// * Shut down 16 weeks' worth of blocks after the estimated release block height.
// * A warning is shown during the 2 weeks' worth of blocks prior to shut down.
static const int APPROX_RELEASE_HEIGHT = 800000;
// * Shut down WEEKS_UNTIL_DEPRECATION weeks' worth of blocks after the estimated release block height.
// * A warning is shown during the DEPRECATION_WARN_LIMIT worth of blocks prior to shut down.
static const int WEEKS_UNTIL_DEPRECATION = 52;
static const int DEPRECATION_HEIGHT = APPROX_RELEASE_HEIGHT + (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 24);
static const int DEPRECATION_HEIGHT = 1400000;
static const int APPROX_RELEASE_HEIGHT = DEPRECATION_HEIGHT - (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 60);
// Number of blocks before deprecation to warn users
static const int DEPRECATION_WARN_LIMIT = 60 * 24 * 60; // 2 months

View File

@@ -22,13 +22,20 @@ curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dp
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CEAL\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MESH\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MNZ\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CHIPS\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"AXO\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"ETOMIC\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BTCH\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CHAIN\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"VOTE2018\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"NINJA\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"OOT\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BNTN\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"PRLPAY\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"DSEC\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"GLXT\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"EQL\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"ZILLA\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CHIPS\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"GAME\",\"freq\":5,\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"RFOX\",\"freq\":10,\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"VRSC\",\"freq\":10,\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"SEC\",\"pubkey\":\"$pubkey\"}"

View File

@@ -1,30 +1,8 @@
#!/bin/bash
#set -x
echo revs; fiat/revs $1 $2 $3 $4
echo supernet; fiat/supernet $1 $2 $3 $4
echo dex; fiat/dex $1 $2 $3 $4
echo pangea; fiat/pangea $1 $2 $3 $4
echo jumblr; fiat/jumblr $1 $2 $3 $4
echo bet; fiat/bet $1 $2 $3 $4
echo crypto; fiat/crypto $1 $2 $3 $4
echo hodl; fiat/hodl $1 $2 $3 $4
echo mshark; fiat/mshark $1 $2 $3 $4
echo bots; fiat/bots $1 $2 $3 $4
echo mgw; fiat/mgw $1 $2 $3 $4
echo coqui; fiat/coqui $1 $2 $3 $4
echo wlc; fiat/wlc $1 $2 $3 $4
echo kv; fiat/kv $1 $2 $3 $4
echo ceal; fiat/ceal $1 $2 $3 $4
echo mesh; fiat/mesh $1 $2 $3 $4
echo mnz; fiat/mnz $1 $2 $3 $4
echo axo; fiat/axo $1 $2 $3 $4
echo etomic; fiat/etomic $1 $2 $3 $4
echo btch; fiat/btch $1 $2 $3 $4
echo pizza; fiat/pizza $1 $2 $3 $4
echo beer; fiat/beer $1 $2 $3 $4
echo vote2018; fiat/vote2018 $1 $2 $3 $4
echo ninja; fiat/ninja $1 $2 $3 $4
echo oot; fiat/oot $1 $2 $3 $4
echo bntn; fiat/bntn $1 $2 $3 $4
echo chain; fiat/chain $1 $2 $3 $4
echo prlpay; fiat/prlpay $1 $2 $3 $4
args="$@"
./listassetchains | while read chain; do
echo $chain
./komodo-cli --ac_name=$chain $args
done

2
src/fiat/dsec Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=DSEC $1 $2 $3 $4 $5 $6

2
src/fiat/eql Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=EQL $1 $2 $3 $4 $5 $6

2
src/fiat/glxt Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=GLXT $1 $2 $3 $4 $5 $6

2
src/fiat/rfox Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=RFOX $1 $2 $3 $4 $5 $6

2
src/fiat/sec Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=SEC $1 $2 $3 $4 $5 $6

2
src/fiat/vrsc Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=VRSC $1 $2 $3 $4 $5 $6

2
src/fiat/zilla Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
./komodo-cli -ac_name=ZILLA $1 $2 $3 $4 $5 $6

121
src/importcoin.cpp Normal file
View File

@@ -0,0 +1,121 @@
#include "crosschain.h"
#include "importcoin.h"
#include "cc/utils.h"
#include "coins.h"
#include "hash.h"
#include "script/cc.h"
#include "primitives/transaction.h"
CTransaction MakeImportCoinTransaction(const TxProof proof, const CTransaction burnTx, const std::vector<CTxOut> payouts)
{
std::vector<uint8_t> payload = E_MARSHAL(ss << EVAL_IMPORTCOIN);
CMutableTransaction mtx;
mtx.vin.push_back(CTxIn(COutPoint(burnTx.GetHash(), 10e8), CScript() << payload));
mtx.vout = payouts;
auto importData = E_MARSHAL(ss << proof; ss << burnTx);
mtx.vout.insert(mtx.vout.begin(), CTxOut(0, CScript() << OP_RETURN << importData));
return CTransaction(mtx);
}
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector<CTxOut> payouts)
{
std::vector<uint8_t> opret = E_MARSHAL(ss << VARINT(targetCCid);
ss << targetSymbol;
ss << SerializeHash(payouts));
return CTxOut(value, CScript() << OP_RETURN << opret);
}
bool UnmarshalImportTx(const CTransaction &importTx, TxProof &proof, CTransaction &burnTx,
std::vector<CTxOut> &payouts)
{
std::vector<uint8_t> vData;
GetOpReturnData(importTx.vout[0].scriptPubKey, vData);
if (importTx.vout.size() < 1) return false;
payouts = std::vector<CTxOut>(importTx.vout.begin()+1, importTx.vout.end());
return importTx.vin.size() == 1 &&
importTx.vin[0].scriptSig == (CScript() << E_MARSHAL(ss << EVAL_IMPORTCOIN)) &&
E_UNMARSHAL(vData, ss >> proof; ss >> burnTx);
}
bool UnmarshalBurnTx(const CTransaction &burnTx, std::string &targetSymbol, uint32_t *targetCCid, uint256 &payoutsHash)
{
std::vector<uint8_t> burnOpret;
if (burnTx.vout.size() == 0) return false;
GetOpReturnData(burnTx.vout[0].scriptPubKey, burnOpret);
return E_UNMARSHAL(burnOpret, ss >> VARINT(*targetCCid);
ss >> targetSymbol;
ss >> payoutsHash);
}
/*
* Required by main
*/
CAmount GetCoinImportValue(const CTransaction &tx)
{
TxProof proof;
CTransaction burnTx;
std::vector<CTxOut> payouts;
if (UnmarshalImportTx(tx, proof, burnTx, payouts)) {
return burnTx.vout.size() ? burnTx.vout[0].nValue : 0;
}
return 0;
}
/*
* CoinImport is different enough from normal script execution that it's not worth
* making all the mods neccesary in the interpreter to do the dispatch correctly.
*/
bool VerifyCoinImport(const CScript& scriptSig, TransactionSignatureChecker& checker, CValidationState &state)
{
auto pc = scriptSig.begin();
opcodetype opcode;
std::vector<uint8_t> evalScript;
auto f = [&] () {
if (!scriptSig.GetOp(pc, opcode, evalScript))
return false;
if (pc != scriptSig.end())
return false;
if (evalScript.size() == 0)
return false;
if (evalScript.begin()[0] != EVAL_IMPORTCOIN)
return false;
// Ok, all looks good so far...
CC *cond = CCNewEval(evalScript);
bool out = checker.CheckEvalCondition(cond);
cc_free(cond);
return out;
};
return f() ? true : state.Invalid(false, 0, "invalid-coin-import");
}
void AddImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs, int nHeight)
{
uint256 burnHash = importTx.vin[0].prevout.hash;
CCoinsModifier modifier = inputs.ModifyCoins(burnHash);
modifier->nHeight = nHeight;
modifier->nVersion = 1;
modifier->vout.push_back(CTxOut(0, CScript() << OP_0));
}
void RemoveImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs)
{
uint256 burnHash = importTx.vin[0].prevout.hash;
inputs.ModifyCoins(burnHash)->Clear();
}
int ExistsImportTombstone(const CTransaction &importTx, const CCoinsViewCache &inputs)
{
uint256 burnHash = importTx.vin[0].prevout.hash;
return inputs.HaveCoins(burnHash);
}

Some files were not shown because too many files have changed in this diff Show More