@@ -0,0 +1,52 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
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 | |||
=H4Qj | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,90 @@ | |||
RESEARCH LICENSE | |||
Version 1.1.2 | |||
I. DEFINITIONS. | |||
"Licensee " means You and any other party that has entered into and has in effect a version of this License. | |||
โLicensorโ means DERO PROJECT(GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8) and its successors and assignees. | |||
"Modifications" means any (a) change or addition to the Technology or (b) new source or object code implementing any portion of the Technology. | |||
"Research Use" means research, evaluation, or development for the purpose of advancing knowledge, teaching, learning, or customizing the Technology for personal use. Research Use expressly excludes use or distribution for direct or indirect commercial (including strategic) gain or advantage. | |||
"Technology" means the source code, object code and specifications of the technology made available by Licensor pursuant to this License. | |||
"Technology Site" means the website designated by Licensor for accessing the Technology. | |||
"You" means the individual executing this License or the legal entity or entities represented by the individual executing this License. | |||
II. PURPOSE. | |||
Licensor is licensing the Technology under this Research License (the "License") to promote research, education, innovation, and development using the Technology. | |||
COMMERCIAL USE AND DISTRIBUTION OF TECHNOLOGY AND MODIFICATIONS IS PERMITTED ONLY UNDER AN APPROPRIATE COMMERCIAL USE LICENSE AVAILABLE FROM LICENSOR AT <url>. | |||
III. RESEARCH USE RIGHTS. | |||
A. Subject to the conditions contained herein, Licensor grants to You a non-exclusive, non-transferable, worldwide, and royalty-free license to do the following for Your Research Use only: | |||
1. reproduce, create Modifications of, and use the Technology alone, or with Modifications; | |||
2. share source code of the Technology alone, or with Modifications, with other Licensees; | |||
3. distribute object code of the Technology, alone, or with Modifications, to any third parties for Research Use only, under a license of Your choice that is consistent with this License; and | |||
4. publish papers and books discussing the Technology which may include relevant excerpts that do not in the aggregate constitute a significant portion of the Technology. | |||
B. Residual Rights. You may use any information in intangible form that you remember after accessing the Technology, except when such use violates Licensor's copyrights or patent rights. | |||
C. No Implied Licenses. Other than the rights granted herein, Licensor retains all rights, title, and interest in Technology , and You retain all rights, title, and interest in Your Modifications and associated specifications, subject to the terms of this License. | |||
D. Open Source Licenses. Portions of the Technology may be provided with notices and open source licenses from open source communities and third parties that govern the use of those portions, and any licenses granted hereunder do not alter any rights and obligations you may have under such open source licenses, however, the disclaimer of warranty and limitation of liability provisions in this License will apply to all Technology in this distribution. | |||
IV. INTELLECTUAL PROPERTY REQUIREMENTS | |||
As a condition to Your License, You agree to comply with the following restrictions and responsibilities: | |||
A. License and Copyright Notices. You must include a copy of this License in a Readme file for any Technology or Modifications you distribute. You must also include the following statement, "Use and distribution of this technology is subject to the Java Research License included herein", (a) once prominently in the source code tree and/or specifications for Your source code distributions, and (b) once in the same file as Your copyright or proprietary notices for Your binary code distributions. You must cause any files containing Your Modification to carry prominent notice stating that You changed the files. You must not remove or alter any copyright or other proprietary notices in the Technology. | |||
B. Licensee Exchanges. Any Technology and Modifications You receive from any Licensee are governed by this License. | |||
V. GENERAL TERMS. | |||
A. Disclaimer Of Warranties. | |||
TECHNOLOGY IS PROVIDED "AS IS", WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT ANY SUCH TECHNOLOGY IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING OF THIRD PARTY RIGHTS. YOU AGREE THAT YOU BEAR THE ENTIRE RISK IN CONNECTION WITH YOUR USE AND DISTRIBUTION OF ANY AND ALL TECHNOLOGY UNDER THIS LICENSE. | |||
B. Infringement; Limitation Of Liability. | |||
1. If any portion of, or functionality implemented by, the Technology becomes the subject of a claim or threatened claim of infringement ("Affected Materials"), Licensor may, in its unrestricted discretion, suspend Your rights to use and distribute the Affected Materials under this License. Such suspension of rights will be effective immediately upon Licensor's posting of notice of suspension on the Technology Site. | |||
2. IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES IN CONNECTION WITH OR ARISING OUT OF THIS LICENSE (INCLUDING, WITHOUT LIMITATION, LOSS OF PROFITS, USE, DATA, OR ECONOMIC ADVANTAGE OF ANY SORT), HOWEVER IT ARISES AND ON ANY THEORY OF LIABILITY (including negligence), WHETHER OR NOT LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. LIABILITY UNDER THIS SECTION V.B.2 SHALL BE SO LIMITED AND EXCLUDED, NOTWITHSTANDING FAILURE OF THE ESSENTIAL PURPOSE OF ANY REMEDY. | |||
C. Termination. | |||
1. You may terminate this License at any time by notifying Licensor in writing. | |||
2. All Your rights will terminate under this License if You fail to comply with any of its material terms or conditions and do not cure such failure within thirty (30) days after becoming aware of such noncompliance. | |||
3. Upon termination, You must discontinue all uses and distribution of the Technology , and all provisions of this Section V shall survive termination. | |||
D. Miscellaneous. | |||
1. Trademark. You agree to comply with Licensor's Trademark & Logo Usage Requirements, if any and as modified from time to time, available at the Technology Site. Except as expressly provided in this License, You are granted no rights in or to any Licensor's trademarks now or hereafter used or licensed by Licensor. | |||
2. Integration. This License represents the complete agreement of the parties concerning the subject matter hereof. | |||
3. Severability. If any provision of this License is held unenforceable, such provision shall be reformed to the extent necessary to make it enforceable unless to do so would defeat the intent of the parties, in which case, this License shall terminate. | |||
4. Governing Law. This License is governed by the laws of the United States and the State of California, as applied to contracts entered into and performed in California between California residents. In no event shall this License be construed against the drafter. | |||
5. Export Control. You agree to comply with the U.S. export controlsand trade laws of other countries that apply to Technology and Modifications. | |||
READ ALL THE TERMS OF THIS LICENSE CAREFULLY BEFORE ACCEPTING. | |||
BY CLICKING ON THE YES BUTTON BELOW OR USING THE TECHNOLOGY, YOU ARE ACCEPTING AND AGREEING TO ABIDE BY THE TERMS AND CONDITIONS OF THIS LICENSE. YOU MUST BE AT LEAST 18 YEARS OF AGE AND OTHERWISE COMPETENT TO ENTER INTO CONTRACTS. | |||
IF YOU DO NOT MEET THESE CRITERIA, OR YOU DO NOT AGREE TO ANY OF THE TERMS OF THIS LICENSE, DO NOT USE THIS SOFTWARE IN ANY FORM. | |||
@@ -0,0 +1,162 @@ | |||
# DERO: Secure, Private CryptoNote DAG Blockchain with Smart Contracts | |||
## ABOUT DERO PROJECT | |||
DERO is decentralized DAG(Directed Acyclic Graph) based blockchain with enhanced reliability, privacy, security, and usability. Consensus algorithm is PoW based on original cryptonight. DERO is industry leading and the first blockchain to have bulletproofs, TLS encrypted Network. | |||
### DERO blockchain has the following salient features: | |||
- DAG Based: No orphan blocks, No soft-forks. | |||
- 12 Second Block time. | |||
- Extremely fast transactions with 2 minutes confirmation time. | |||
- SSL/TLS P2P Network. | |||
- CryptoNote: Fully Encrypted Blockchain | |||
- BulletProofs: Zero Knowledge range-proofs(NIZK). | |||
- Ring signatures. | |||
- Fully Auditable Supply. | |||
- DERO blockchain is written from scratch in Golang. | |||
- Developed and maintained by original developers. | |||
### DERO DAG | |||
DERO DAG implementation builds outs a main chain from the DAG network of blocks which refers to main blocks (100% reward) and side blocks (67% rewards). Side blocks contribute to chain PoW security and thus traditional 51% attacks are not possible on DERO network. If DERO network finds another block at the same height, instead of choosing one, DERO include both blocks. Thus, rendering the 51% attack futile. | |||
Traditional Blockchains process blocks as single unit of computation(if a double-spend tx occurs within the block, entire block is rejected). However DERO network accepts such blocks since DERO blockchain considers transaction as a single unit of computation.DERO blocks may contain duplicate or double-spend transactions which are filtered by client protocol and ignored by the network. DERO DAG processes transactions atomically one transaction at a time. | |||
**DERO DAG in action** | |||
 | |||
## Downloads | |||
| Operating System | Download | | |||
| ---------------- | ---------------------------------------- | | |||
| Windows 32 | https://github.com/deroproject/derosuite/releases | | |||
| Windows 64 | https://github.com/deroproject/derosuite/releases | | |||
| Mac 10.8 & Later | https://github.com/deroproject/derosuite/releases | | |||
| Linux 32 | https://github.com/deroproject/derosuite/releases | | |||
| Linux 64 | https://github.com/deroproject/derosuite/releases | | |||
| OpenBSD 64 | https://github.com/deroproject/derosuite/releases | | |||
| FreeBSD 64 | https://github.com/deroproject/derosuite/releases | | |||
| Linux ARM 64 | https://github.com/deroproject/derosuite/releases | | |||
| More Builds | https://github.com/deroproject/derosuite/releases | | |||
### Build from sources: | |||
In go workspace: **go get -u github.com/deroproject/derosuite/...** | |||
Check bin folder for derod, explorer and wallet binaries. Use golang-1.10.3 version minimum. | |||
### DERO Quickstart | |||
1. Choose your Operating System and [download Dero software](https://github.com/deroproject/derosuite/releases) | |||
2. Extract the file and change to extracted folder in cmd prompt. | |||
3. Start derod daemon and wait to fully sync till prompt goes green. | |||
4. Open new cmd prompt and run dero-wallet-cli. | |||
For detailed walk through to create/restore Dero wallet pls see: [Create/Restore DERO Wallet in one minute](https://forum.dero.io/t/create-backup-restore-dero-wallet-in-one-minute/110) | |||
**DERO Daemon in action** | |||
 | |||
**DERO Wallet in action** | |||
 | |||
## Technical | |||
For specific details of current DERO core (daemon) implementation and capabilities, see below: | |||
1. **DAG:** No orphan blocks, No soft-forks. | |||
2. **BulletProofs:** Zero Knowledge range-proofs(NIZK) | |||
3. **Cryptonight Hash:** This is memory-bound algorithm. This provides assurance that all miners are equal. ( No miner has any advantage over common miners). | |||
4. **P2P Protocol:** This layers controls exchange of blocks, transactions and blockchain itself. | |||
5. **Pederson Commitment:** (Part of ring confidential transactions): Pederson commitment algorithm is a cryptographic primitive that allows user to commit to a chosen value while keeping it hidden to others. Pederson commitment is used to hide all amounts without revealing the actual amount. It is a homomorphic commitment scheme. | |||
6. **Borromean Signature:** (Part of ring confidential transactions): Borromean Signatures are used to prove that the commitment has a specific value, without revealing the value itself. | |||
7. **Additive Homomorphic Encryption:** Additive Homomorphic Encryption is used to prove that sum of encrypted Input transaction amounts is EQUAL to sum of encrypted output amounts. This is based on Homomorphic Pederson commitment scheme. | |||
8. **Multilayered Linkable Spontaneous Anonymous Group (MLSAG) :** (Part of ring confidential transactions): MLSAG gives DERO untraceability and increases privacy and fungibility. MLSAG is a user controlled parameter ( Mixin) which the user can change to improve his privacy. Mixin of minimal amount is enforced and user cannot disable it. | |||
9. **Ring Confidential Transactions:** Gives untraceability , privacy and fungibility while making sure that the system is stable and secure. | |||
10. **Core-Consensus Protocol implemented:** Consensus protocol serves 2 major purpose | |||
1. Protects the system from adversaries and protects it from forking and tampering. | |||
2. Next block in the chain is the one and only correct version of truth ( balances). | |||
11. **Proof-of-Work(PoW) algorithm:** PoW part of core consensus protocol which is used to cryptographically prove that X amount of work has been done to successfully find a block. | |||
12. **Difficulty algorithm**: Difficulty algorithm controls the system so as blocks are found roughly at the same speed, irrespective of the number and amount of mining power deployed. | |||
13. **Serialization/De-serialization of blocks**: Capability to encode/decode/process blocks . | |||
14. **Serialization/De-serialization of transactions**: Capability to encode/decode/process transactions. | |||
15. **Transaction validity and verification**: Any transactions flowing within the DERO network are validated,verified. | |||
16. **Socks proxy:** Socks proxy has been implemented and integrated within the daemon to decrease user identifiability and improve user anonymity. | |||
17. **Interactive daemon** can print blocks, txs, even entire blockchain from within the daemon | |||
18. **status, diff, print_bc, print_block, print_tx** and several other commands implemented | |||
19. GO DERO Daemon has both mainnet, testnet support. | |||
20. **Enhanced Reliability, Privacy, Security, Useability, Portabilty assured.** For discussion on each point how pls visit forum. | |||
## Crypto | |||
Secure and fast crypto is the basic necessity of this project and adequate amount of time has been devoted to develop/study/implement/audit it. Most of the crypto such as ring signatures have been studied by various researchers and are in production by number of projects. As far as the Bulletproofs are considered, since DERO is the first one to implement/deploy, they have been given a more detailed look. First, a bare bones bulletproofs was implemented, then implementations in development were studied (Benedict Bunz,XMR, Dalek Bulletproofs) and thus improving our own implementation.Some new improvements were discovered and implemented (There are number of other improvements which are not explained here). Major improvements are in the Double-Base Double-Scalar Multiplication while validating bulletproofs. A typical bulletproof takes ~15-17 ms to verify. Optimised bulletproofs takes ~1 to ~2 ms(simple bulletproof, no aggregate/batching). Since, in the case of bulletproofs the bases are fixed, we can use precompute table to convert 64*2 Base Scalar multiplication into doublings and additions (NOTE: We do not use Bos-Coster/Pippienger methods). This time can be again easily decreased to .5 ms with some more optimizations.With batching and aggregation, 5000 range-proofs (~2500 TX) can be easily verified on even a laptop. The implementation for bulletproofs is in github.com/deroproject/derosuite/crypto/ringct/bulletproof.go , optimized version is in github.com/deroproject/derosuite/crypto/ringct/bulletproof_ultrafast.go | |||
There are other optimizations such as base-scalar multiplication could be done in less than a microsecond. Some of these optimizations are not yet deployed and may be deployed at a later stage. | |||
### About Dero Rocket Bulletproofs | |||
- Dero ultrafast bulletproofs optimization techniques in the form used did not exist anywhere in publicly available cryptography literature at the time of implementation. Please contact for any source/reference to include here if it exists. Ultrafast optimizations verifies Dero bulletproofs 10 times faster than other/original bulletproof implementations. See: https://github.com/deroproject/derosuite/blob/master/crypto/ringct/bulletproof_ultrafast.go | |||
- DERO rocket bulletproof implementations are hardened, which protects DERO from certain class of attacks. | |||
- DERO rocket bulletproof transactions structures are not compatible with other implementations. | |||
Also there are several optimizations planned in near future in Dero rocket bulletproofs which will lead to several times performance boost. Presently they are under study for bugs, verifications, compatibilty etc. | |||
For technical issues and discussion, please visit https://forum.dero.io | |||
``` | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
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 | |||
=H4Qj | |||
-----END PGP PUBLIC KEY BLOCK----- | |||
``` | |||
@@ -0,0 +1,90 @@ | |||
RESEARCH LICENSE | |||
Version 1.1.2 | |||
I. DEFINITIONS. | |||
"Licensee " means You and any other party that has entered into and has in effect a version of this License. | |||
โLicensorโ means DERO PROJECT(GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8) and its successors and assignees. | |||
"Modifications" means any (a) change or addition to the Technology or (b) new source or object code implementing any portion of the Technology. | |||
"Research Use" means research, evaluation, or development for the purpose of advancing knowledge, teaching, learning, or customizing the Technology for personal use. Research Use expressly excludes use or distribution for direct or indirect commercial (including strategic) gain or advantage. | |||
"Technology" means the source code, object code and specifications of the technology made available by Licensor pursuant to this License. | |||
"Technology Site" means the website designated by Licensor for accessing the Technology. | |||
"You" means the individual executing this License or the legal entity or entities represented by the individual executing this License. | |||
II. PURPOSE. | |||
Licensor is licensing the Technology under this Research License (the "License") to promote research, education, innovation, and development using the Technology. | |||
COMMERCIAL USE AND DISTRIBUTION OF TECHNOLOGY AND MODIFICATIONS IS PERMITTED ONLY UNDER AN APPROPRIATE COMMERCIAL USE LICENSE AVAILABLE FROM LICENSOR AT <url>. | |||
III. RESEARCH USE RIGHTS. | |||
A. Subject to the conditions contained herein, Licensor grants to You a non-exclusive, non-transferable, worldwide, and royalty-free license to do the following for Your Research Use only: | |||
1. reproduce, create Modifications of, and use the Technology alone, or with Modifications; | |||
2. share source code of the Technology alone, or with Modifications, with other Licensees; | |||
3. distribute object code of the Technology, alone, or with Modifications, to any third parties for Research Use only, under a license of Your choice that is consistent with this License; and | |||
4. publish papers and books discussing the Technology which may include relevant excerpts that do not in the aggregate constitute a significant portion of the Technology. | |||
B. Residual Rights. You may use any information in intangible form that you remember after accessing the Technology, except when such use violates Licensor's copyrights or patent rights. | |||
C. No Implied Licenses. Other than the rights granted herein, Licensor retains all rights, title, and interest in Technology , and You retain all rights, title, and interest in Your Modifications and associated specifications, subject to the terms of this License. | |||
D. Open Source Licenses. Portions of the Technology may be provided with notices and open source licenses from open source communities and third parties that govern the use of those portions, and any licenses granted hereunder do not alter any rights and obligations you may have under such open source licenses, however, the disclaimer of warranty and limitation of liability provisions in this License will apply to all Technology in this distribution. | |||
IV. INTELLECTUAL PROPERTY REQUIREMENTS | |||
As a condition to Your License, You agree to comply with the following restrictions and responsibilities: | |||
A. License and Copyright Notices. You must include a copy of this License in a Readme file for any Technology or Modifications you distribute. You must also include the following statement, "Use and distribution of this technology is subject to the Java Research License included herein", (a) once prominently in the source code tree and/or specifications for Your source code distributions, and (b) once in the same file as Your copyright or proprietary notices for Your binary code distributions. You must cause any files containing Your Modification to carry prominent notice stating that You changed the files. You must not remove or alter any copyright or other proprietary notices in the Technology. | |||
B. Licensee Exchanges. Any Technology and Modifications You receive from any Licensee are governed by this License. | |||
V. GENERAL TERMS. | |||
A. Disclaimer Of Warranties. | |||
TECHNOLOGY IS PROVIDED "AS IS", WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT ANY SUCH TECHNOLOGY IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING OF THIRD PARTY RIGHTS. YOU AGREE THAT YOU BEAR THE ENTIRE RISK IN CONNECTION WITH YOUR USE AND DISTRIBUTION OF ANY AND ALL TECHNOLOGY UNDER THIS LICENSE. | |||
B. Infringement; Limitation Of Liability. | |||
1. If any portion of, or functionality implemented by, the Technology becomes the subject of a claim or threatened claim of infringement ("Affected Materials"), Licensor may, in its unrestricted discretion, suspend Your rights to use and distribute the Affected Materials under this License. Such suspension of rights will be effective immediately upon Licensor's posting of notice of suspension on the Technology Site. | |||
2. IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES IN CONNECTION WITH OR ARISING OUT OF THIS LICENSE (INCLUDING, WITHOUT LIMITATION, LOSS OF PROFITS, USE, DATA, OR ECONOMIC ADVANTAGE OF ANY SORT), HOWEVER IT ARISES AND ON ANY THEORY OF LIABILITY (including negligence), WHETHER OR NOT LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. LIABILITY UNDER THIS SECTION V.B.2 SHALL BE SO LIMITED AND EXCLUDED, NOTWITHSTANDING FAILURE OF THE ESSENTIAL PURPOSE OF ANY REMEDY. | |||
C. Termination. | |||
1. You may terminate this License at any time by notifying Licensor in writing. | |||
2. All Your rights will terminate under this License if You fail to comply with any of its material terms or conditions and do not cure such failure within thirty (30) days after becoming aware of such noncompliance. | |||
3. Upon termination, You must discontinue all uses and distribution of the Technology , and all provisions of this Section V shall survive termination. | |||
D. Miscellaneous. | |||
1. Trademark. You agree to comply with Licensor's Trademark & Logo Usage Requirements, if any and as modified from time to time, available at the Technology Site. Except as expressly provided in this License, You are granted no rights in or to any Licensor's trademarks now or hereafter used or licensed by Licensor. | |||
2. Integration. This License represents the complete agreement of the parties concerning the subject matter hereof. | |||
3. Severability. If any provision of this License is held unenforceable, such provision shall be reformed to the extent necessary to make it enforceable unless to do so would defeat the intent of the parties, in which case, this License shall terminate. | |||
4. Governing Law. This License is governed by the laws of the United States and the State of California, as applied to contracts entered into and performed in California between California residents. In no event shall this License be construed against the drafter. | |||
5. Export Control. You agree to comply with the U.S. export controlsand trade laws of other countries that apply to Technology and Modifications. | |||
READ ALL THE TERMS OF THIS LICENSE CAREFULLY BEFORE ACCEPTING. | |||
BY CLICKING ON THE YES BUTTON BELOW OR USING THE TECHNOLOGY, YOU ARE ACCEPTING AND AGREEING TO ABIDE BY THE TERMS AND CONDITIONS OF THIS LICENSE. YOU MUST BE AT LEAST 18 YEARS OF AGE AND OTHERWISE COMPETENT TO ENTER INTO CONTRACTS. | |||
IF YOU DO NOT MEET THESE CRITERIA, OR YOU DO NOT AGREE TO ANY OF THE TERMS OF THIS LICENSE, DO NOT USE THIS SOFTWARE IN ANY FORM. | |||
@@ -0,0 +1,171 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package address | |||
import "fmt" | |||
import "bytes" | |||
import "encoding/binary" | |||
import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/crypto" | |||
// see https://cryptonote.org/cns/cns007.txt to understand address more | |||
type Address struct { | |||
Network uint64 | |||
SpendKey crypto.Key // these are public keys only | |||
ViewKey crypto.Key // these are public keys only | |||
PaymentID []byte //integrated payment id is 8 bytes | |||
// 8 byte version is encrypted on the blockchain | |||
// 32 byte version is dumped on the chain openly | |||
} | |||
const ChecksumLength = 4 | |||
type Checksum [ChecksumLength]byte | |||
func GetChecksum(data ...[]byte) (result Checksum) { | |||
keccak256 := crypto.Keccak256(data...) | |||
copy(result[:], keccak256[:4]) | |||
return | |||
} | |||
func (a *Address) Base58() (result string) { | |||
prefix := make([]byte, 9, 9) | |||
n := binary.PutUvarint(prefix, a.Network) | |||
prefix = prefix[:n] | |||
// convert address to string ( include payment ID if prefix says so ) | |||
switch a.Network { | |||
case 19: | |||
fallthrough // for testing purpose monero integrated address | |||
case config.Mainnet.Public_Address_Prefix_Integrated: | |||
fallthrough | |||
case config.Testnet.Public_Address_Prefix_Integrated: | |||
checksum := GetChecksum(prefix, a.SpendKey[:], a.ViewKey[:], a.PaymentID) | |||
result = EncodeDeroBase58(prefix, a.SpendKey[:], a.ViewKey[:], a.PaymentID, checksum[:]) | |||
// normal addresses without prefix | |||
case config.Mainnet.Public_Address_Prefix: | |||
fallthrough | |||
case config.Testnet.Public_Address_Prefix: | |||
fallthrough | |||
default: | |||
checksum := GetChecksum(prefix, a.SpendKey[:], a.ViewKey[:]) | |||
result = EncodeDeroBase58(prefix, a.SpendKey[:], a.ViewKey[:], checksum[:]) | |||
} | |||
return | |||
} | |||
// stringifier | |||
func (a Address) String() string { | |||
return a.Base58() | |||
} | |||
// tells whether address is mainnet address | |||
func (a *Address) IsMainnet() bool { | |||
if a.Network == config.Mainnet.Public_Address_Prefix || | |||
a.Network == config.Mainnet.Public_Address_Prefix_Integrated { | |||
return true | |||
} | |||
return false | |||
} | |||
// tells whether address is mainnet address | |||
func (a *Address) IsIntegratedAddress() bool { | |||
if a.Network == config.Testnet.Public_Address_Prefix_Integrated || | |||
a.Network == config.Mainnet.Public_Address_Prefix_Integrated { | |||
return true | |||
} | |||
return false | |||
} | |||
// tells whether address belongs to DERO Network | |||
func (a *Address) IsDERONetwork() bool { | |||
if a.Network == config.Mainnet.Public_Address_Prefix || | |||
a.Network == config.Mainnet.Public_Address_Prefix_Integrated || | |||
a.Network == config.Testnet.Public_Address_Prefix || | |||
a.Network == config.Testnet.Public_Address_Prefix_Integrated { | |||
return true | |||
} | |||
return false | |||
} | |||
func NewAddress(address string) (result *Address, err error) { | |||
raw := DecodeDeroBase58(address) | |||
// donot compare length to support much more user base and be compatible with cryptonote | |||
if len(raw) < 69 { // 1 byte prefix + 32 byte key + 32 byte key + 4 byte checksum | |||
err = fmt.Errorf("Address is not complete") | |||
return | |||
} | |||
checksum := GetChecksum(raw[:len(raw)-4]) | |||
if bytes.Compare(checksum[:], raw[len(raw)-4:]) != 0 { | |||
err = fmt.Errorf("Checksum failed") | |||
return | |||
} | |||
raw = raw[0 : len(raw)-4] // remove the checksum | |||
// parse network first | |||
address_prefix, done := binary.Uvarint(raw) | |||
if done <= 0 { | |||
err = fmt.Errorf("Network could not be parsed in address\n") | |||
return | |||
} | |||
raw = raw[done:] | |||
result = &Address{ | |||
Network: address_prefix, | |||
//SpendKey: raw[0:32], | |||
//ViewKey: raw[32:64], | |||
} | |||
copy(result.SpendKey[:], raw[0:32]) | |||
copy(result.ViewKey[:], raw[32:64]) | |||
// | |||
switch address_prefix { // if network id is integrated address | |||
case 19: | |||
fallthrough //Monero_MainNetwork_Integrated: for testing purposes only for compatible reasons | |||
case config.Mainnet.Public_Address_Prefix_Integrated: | |||
fallthrough // DERO mainnet integrated address | |||
case config.Testnet.Public_Address_Prefix_Integrated: // DERO testnet integrated address | |||
if len(raw[64:]) == 8 { // 8 byte encrypted payment id + 4 bytes | |||
result.PaymentID = raw[64:] | |||
} else if len(raw[64:]) == 32 { // 32 byte unencrypted payment ID | |||
result.PaymentID = raw[64:] | |||
} else { | |||
err = fmt.Errorf("Invalid payment ID in address\n") | |||
return | |||
} | |||
} | |||
return | |||
} | |||
// create a new address from keys | |||
func NewAddressFromKeys(spendkey, viewkey crypto.Key) (result *Address) { | |||
result = &Address{ | |||
Network: config.Mainnet.Public_Address_Prefix, | |||
SpendKey: spendkey, | |||
ViewKey: viewkey, | |||
} | |||
return | |||
} |
@@ -0,0 +1,250 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package address | |||
import "fmt" | |||
import "bytes" | |||
import "testing" | |||
import "encoding/hex" | |||
import "github.com/deroproject/derosuite/config" | |||
func TestAddressError(t *testing.T) { | |||
_, err := NewAddress("") | |||
want := fmt.Errorf("Address is not complete") | |||
if err.Error() != want.Error() { | |||
t.Fatalf("want: %s, got: %s", want, err) | |||
} | |||
_, err = NewAddress("dERoNzsi5WW1ABhQ1UGLwoLqBU6sbzvyuS4cCi4PGzW7QRM5TH4MUf3QvZUBNJCYSDPw6K495eroGe24cf75uDdD2QwWy9pchN") | |||
want = fmt.Errorf("Checksum failed") | |||
if err.Error() != want.Error() { | |||
t.Fatalf("want: %s, got: %s", want, err) | |||
} | |||
} | |||
func TestAddress(t *testing.T) { | |||
const Monero_MainNetwork = 18 | |||
const Monero_TestNetwork = 53 | |||
tests := []struct { | |||
name string | |||
Network uint64 | |||
SpendingKeyHex string | |||
ViewingKeyHex string | |||
Address string | |||
}{ | |||
{ | |||
name: "generic", | |||
Network: Monero_MainNetwork, | |||
SpendingKeyHex: "8c1a9d5ff5aaf1c3cdeb2a1be62f07a34ae6b15fe47a254c8bc240f348271679", | |||
ViewingKeyHex: "0a29b163e392eb9416a52907fd7d3b84530f8d02ff70b1f63e72fdcb54cf7fe1", | |||
Address: "46w3n5EGhBeZkYmKvQRsd8UK9GhvcbYWQDobJape3NLMMFEjFZnJ3CnRmeKspubQGiP8iMTwFEX2QiBsjUkjKT4SSPd3fKp", | |||
}, | |||
{ | |||
name: "generic 2", | |||
Network: Monero_MainNetwork, | |||
SpendingKeyHex: "5007b84275af9a173c2080683afce90b2157ab640c18ddd5ce3e060a18a9ce99", | |||
ViewingKeyHex: "27024b45150037b677418fcf11ba9675494ffdf994f329b9f7a8f8402b7934a0", | |||
Address: "44f1Y84r9Lu4tQdLWRxV122rygfhUeVBrcmBaqcYCwUHScmf1ht8DFLXX9YN4T7nPPLcpqYLUdrFiY77nQYeH9RuK9gg4p6", | |||
}, | |||
{ | |||
name: "require 1 padding in middle", | |||
Network: Monero_MainNetwork, | |||
SpendingKeyHex: "6add197bd82866e8bfbf1dc2fdf49873ec5f679059652da549cd806f2b166756", | |||
ViewingKeyHex: "f5cf2897088fda0f7ac1c42491ed7d558a46ee41d0c81d038fd53ff4360afda0", | |||
Address: "45fzHekTd5FfvxWBPYX2TqLPbtWjaofxYUeWCi6BRQXYFYd85sY2qw73bAuKhqY7deFJr6pN3STY81bZ9x2Zf4nGKASksqe", | |||
}, | |||
{ | |||
name: "require 1 padding in last chunk", | |||
Network: Monero_MainNetwork, | |||
SpendingKeyHex: "50defe92d88b19aaf6bf66f061dd4380b79866a4122b25a03bceb571767dbe7b", | |||
ViewingKeyHex: "f8f6f28283921bf5a17f0bcf4306233fc25ce9b6276154ad0de22aebc5c67702", | |||
Address: "44grjkXtDHJVbZgtU1UKnrNXidcHfZ3HWToU5WjR3KgHMjgwrYLjXC6i5vm3HCp4vnBfYaNEyNiuZVwqtHD2SenS1JBRyco", | |||
}, | |||
{ | |||
name: "testnet", | |||
Network: Monero_TestNetwork, | |||
SpendingKeyHex: "8de9cce254e60cd940abf6c77ef344c3a21fad74320e45734fbfcd5870e5c875", | |||
ViewingKeyHex: "27024b45150037b677418fcf11ba9675494ffdf994f329b9f7a8f8402b7934a0", | |||
Address: "9xYZvCDf6aFdLd7Qawg5XHZitWLKoeFvcLHfe5GxsGCFLbXSWeQNKciXX9YN4T7nPPLcpqYLUdrFiY77nQYeH9RuK9bogZJ", | |||
}, | |||
{ | |||
name: "DERO testnet", | |||
Network: config.Testnet.Public_Address_Prefix, | |||
SpendingKeyHex: "ffb4baf32792d38d36c5f1792201d1cff142a10bad6aa088090156a35858739d", | |||
ViewingKeyHex: "0ea428a9608fc9dc06acceea608ac97cc9119647b943941a381306548ee43455", | |||
Address: "dETosYceeTxRZQBk5hQzN51JepzZn5H24JqR96q7mY7ZFo6JhJKPNSKR3vs9ES1ibyQDQgeRheDP6CJbb7AKJY2H9eacz2RtPy", | |||
}, | |||
{ | |||
name: "DERO mainnet requires padding in second block", | |||
Network: config.Mainnet.Public_Address_Prefix, | |||
SpendingKeyHex: "10a80329a700f25c9892a696de768f5bdc73cafe6095d647e5707c04f48c0481", | |||
ViewingKeyHex: "b0fa8ca43a8f07681274ddd8fa891aea4222aa8027dd516bc144317a042547c4", | |||
Address: "dERoNzsi5WW1ABhQ1UGLwoLqBU6sbzvyuS4cCi4PGzW7QRM5TH4MUf3QvZUBNJCYSDPw6K495eroGe24cf75uDdD2QwWy9pchM", | |||
}, | |||
} | |||
var base58 string | |||
var spendingKey, viewingKey []byte | |||
for _, test := range tests { | |||
spendingKey, _ = hex.DecodeString(test.SpendingKeyHex) | |||
viewingKey, _ = hex.DecodeString(test.ViewingKeyHex) | |||
address, err := NewAddress(test.Address) | |||
if err != nil { | |||
t.Fatalf("%s: Failed while parsing address %s", test.name, err) | |||
continue | |||
} | |||
if address.Network != test.Network { | |||
t.Fatalf("%s: want: %d, got: %d", test.name, test.Network, address.Network) | |||
continue | |||
} | |||
if bytes.Compare(address.SpendKey[:], spendingKey) != 0 { | |||
t.Fatalf("%s: want: %x, got: %s", test.name, spendingKey, address.SpendKey) | |||
continue | |||
} | |||
if bytes.Compare(address.ViewKey[:], viewingKey) != 0 { | |||
t.Fatalf("%s: want: %x, got: %s", test.name, viewingKey, address.ViewKey) | |||
continue | |||
} | |||
base58 = address.Base58() | |||
if base58 != test.Address { | |||
t.Fatalf("%s: want: %s, got: %s", test.name, test.Address, base58) | |||
continue | |||
} | |||
} | |||
} | |||
// more explaination here https://monero.stackexchange.com/questions/1910/how-do-payment-ids-work | |||
// test case created from here https://xmr.llcoins.net/addresstests.html | |||
func TestIntegratedAddress(t *testing.T) { | |||
const Monero_MainNetwork = 18 | |||
const Monero_MainNetwork_Integrated = 19 | |||
const Monero_TestNetwork = 53 | |||
tests := []struct { | |||
name string | |||
Network uint64 | |||
NetworkI uint64 | |||
SpendingKeyHex string | |||
ViewingKeyHex string | |||
PaymentID string | |||
Address string | |||
AddressI string | |||
}{ | |||
{ | |||
name: "generic", | |||
Network: Monero_MainNetwork, | |||
NetworkI: Monero_MainNetwork_Integrated, | |||
SpendingKeyHex: "80d3eca27896f549abc41dd941d08a4c82cff165a7f8bc4c3c0841cffd11c095", | |||
ViewingKeyHex: "7849297236cd7c0d6c69a3c8c179c038d3c1c434735741bb3c8995c3c9d6f2ac", | |||
PaymentID: "90470a40196034b5", | |||
Address: "46WGHoGHRT2DKhdr4BxzhXDoFe5NBjNm1Dka5144aXZHS13cAoUQWRq3FE2gcT3LJjAWJ6fGWq8t8YKRqwwit8vmLT6tcxK", | |||
AddressI: "4GCwJc5n2iYDKhdr4BxzhXDoFe5NBjNm1Dka5144aXZHS13cAoUQWRq3FE2gcT3LJjAWJ6fGWq8t8YKRqwwit8vmVs5oxyLeWQsMWmcgkC", | |||
}, | |||
{ | |||
name: "generic", | |||
Network: config.Mainnet.Public_Address_Prefix, | |||
NetworkI: config.Mainnet.Public_Address_Prefix_Integrated, | |||
SpendingKeyHex: "bd7393b76af23611e6e0eb1e4974bcb5688fceea6ad8a1b08435a4e68fcb7b8c", | |||
ViewingKeyHex: "c828aa405d78c3a0b0a7263d2cb82811d4c6ee3374ada5cc753d8196a271b3d2", | |||
PaymentID: "0cbd6e050cf3b73c", | |||
Address: "dERoiVavtPjhWkdEPp17RJLXVoHkr2ucMdEbgGgpskhLb33732LBifWMCZhPga3EcjXoYqfM9jRv3W3bnWUSpdmK5Jur1PhN6P", | |||
AddressI: "dERijfr9y7XhWkdEPp17RJLXVoHkr2ucMdEbgGgpskhLb33732LBifWMCZhPga3EcjXoYqfM9jRv3W3bnWUSpdmKL24FBjG6ctTAEg1jrhDHh", | |||
}, | |||
} | |||
var base58 string | |||
var spendingKey, viewingKey []byte | |||
for _, test := range tests { | |||
spendingKey, _ = hex.DecodeString(test.SpendingKeyHex) | |||
viewingKey, _ = hex.DecodeString(test.ViewingKeyHex) | |||
address, err := NewAddress(test.Address) | |||
if err != nil { | |||
t.Fatalf("%s: Failed while parsing address %s", test.name, err) | |||
continue | |||
} | |||
if address.Network != test.Network { | |||
t.Errorf("%s: want: %d, got: %d", test.name, test.Network, address.Network) | |||
continue | |||
} | |||
if bytes.Compare(address.SpendKey[:], spendingKey) != 0 { | |||
t.Fatalf("%s: want: %x, got: %s", test.name, spendingKey, address.SpendKey) | |||
continue | |||
} | |||
if bytes.Compare(address.ViewKey[:], viewingKey) != 0 { | |||
t.Fatalf("%s: want: %x, got: %s", test.name, viewingKey, address.ViewKey) | |||
continue | |||
} | |||
base58 = address.Base58() | |||
if base58 != test.Address { | |||
t.Fatalf("%s: want: %s, got: %s", test.name, test.Address, base58) | |||
continue | |||
} | |||
address, err = NewAddress(test.AddressI) | |||
if err != nil { | |||
t.Fatalf("%s: Failed while parsing address %s", test.name, err) | |||
continue | |||
} | |||
base58 = address.Base58() | |||
if base58 != test.AddressI { | |||
t.Fatalf("%s: want: %s, got: %s", test.name, test.AddressI, base58) | |||
continue | |||
} | |||
if fmt.Sprintf("%x", address.PaymentID) != test.PaymentID { | |||
t.Fatalf("%s: PaymentID want: %s, got: %s", test.name, test.PaymentID, address.PaymentID) | |||
} | |||
} | |||
} | |||
func Test_Bruteforce_IntegratedAddress(t *testing.T) { | |||
var AddressI string = "dERijfr9y7XhWkdEPp17RJLXVoHkr2ucMdEbgGgpskhLb33732LBifWMCZhPga3EcjXoYqfM9jRv3W3bnWUSpdmKL24FBjG6ctTAEg1jrhDHh" | |||
var PaymentID string = "0cbd6e050cf3b73c" | |||
for i := 0; i < 100000;i++ { | |||
address, err := NewAddress(AddressI) | |||
if err != nil { | |||
t.Fatalf("%s: Failed while parsing address %s", AddressI, err) | |||
continue | |||
} | |||
if fmt.Sprintf("%x",address.PaymentID) != PaymentID{ | |||
t.Fatalf("Payment ID failed at loop %d", i) | |||
} | |||
} | |||
} |
@@ -0,0 +1,127 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package address | |||
import "strings" | |||
import "math/big" | |||
// all characters in the base58 | |||
const BASE58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" | |||
var base58Lookup = map[string]int{ | |||
"1": 0, "2": 1, "3": 2, "4": 3, "5": 4, "6": 5, "7": 6, "8": 7, | |||
"9": 8, "A": 9, "B": 10, "C": 11, "D": 12, "E": 13, "F": 14, "G": 15, | |||
"H": 16, "J": 17, "K": 18, "L": 19, "M": 20, "N": 21, "P": 22, "Q": 23, | |||
"R": 24, "S": 25, "T": 26, "U": 27, "V": 28, "W": 29, "X": 30, "Y": 31, | |||
"Z": 32, "a": 33, "b": 34, "c": 35, "d": 36, "e": 37, "f": 38, "g": 39, | |||
"h": 40, "i": 41, "j": 42, "k": 43, "m": 44, "n": 45, "o": 46, "p": 47, | |||
"q": 48, "r": 49, "s": 50, "t": 51, "u": 52, "v": 53, "w": 54, "x": 55, | |||
"y": 56, "z": 57, | |||
} | |||
var bigBase = big.NewInt(58) | |||
// chunk are max 8 bytes long refer https://cryptonote.org/cns/cns007.txt for more documentation | |||
var bytes_to_base58_length_mapping = []int{ | |||
0, // 0 bytes of input, 0 byte of base58 output | |||
2, // 1 byte of input, 2 bytes of base58 output | |||
3, // 2 byte of input, 3 bytes of base58 output | |||
5, // 3 byte of input, 5 bytes of base58 output | |||
6, // 4 byte of input, 6 bytes of base58 output | |||
7, // 5 byte of input, 7 bytes of base58 output | |||
9, // 6 byte of input, 9 bytes of base58 output | |||
10, // 7 byte of input, 10 bytes of base58 output | |||
11, // 8 byte of input, 11 bytes of base58 output | |||
} | |||
// encode 8 byte chunk with necessary padding | |||
func encodeChunk(raw []byte) (result string) { | |||
remainder := new(big.Int) | |||
remainder.SetBytes(raw) | |||
bigZero := new(big.Int) | |||
for remainder.Cmp(bigZero) > 0 { | |||
current := new(big.Int) | |||
remainder.DivMod(remainder, bigBase, current) | |||
result = string(BASE58[current.Int64()]) + result | |||
} | |||
for i := range bytes_to_base58_length_mapping { | |||
if i == len(raw) { | |||
if len(result) < bytes_to_base58_length_mapping[i] { | |||
result = strings.Repeat("1", (bytes_to_base58_length_mapping[i]-len(result))) + result | |||
} | |||
return result | |||
} | |||
} | |||
return // we never reach here, if inputs are well-formed <= 8 bytes | |||
} | |||
// decode max 11 char base58 to 8 byte chunk as necessary | |||
// proper error handling is not being done | |||
func decodeChunk(encoded string) (result []byte) { | |||
bigResult := big.NewInt(0) | |||
currentMultiplier := big.NewInt(1) | |||
tmp := new(big.Int) | |||
for i := len(encoded) - 1; i >= 0; i-- { | |||
// make sure decoded character is a base58 char , otherwise return | |||
if strings.IndexAny(BASE58, string(encoded[i])) < 0 { | |||
return | |||
} | |||
tmp.SetInt64(int64(base58Lookup[string(encoded[i])])) | |||
tmp.Mul(currentMultiplier, tmp) | |||
bigResult.Add(bigResult, tmp) | |||
currentMultiplier.Mul(currentMultiplier, bigBase) | |||
} | |||
for i := range bytes_to_base58_length_mapping { | |||
if bytes_to_base58_length_mapping[i] == len(encoded) { | |||
result = append([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0}, bigResult.Bytes()...) | |||
return result[len(result)-i:] // return necessary bytes, initial zero appended as per mapping | |||
} | |||
} | |||
return // we never reach here, if inputs are well-formed <= 11 chars | |||
} | |||
// split into 8 byte chunks, process and merge back result | |||
func EncodeDeroBase58(data ...[]byte) (result string) { | |||
var combined []byte | |||
for _, item := range data { | |||
combined = append(combined, item...) | |||
} | |||
fullblocks := len(combined) / 8 | |||
for i := 0; i < fullblocks; i++ { // process any chunks in 8 byte form | |||
result += encodeChunk(combined[i*8 : (i+1)*8]) | |||
} | |||
if len(combined)%8 > 0 { // process last partial block | |||
result += encodeChunk(combined[fullblocks*8:]) | |||
} | |||
return | |||
} | |||
// split into 11 char chunks, process and merge back result | |||
func DecodeDeroBase58(data string) (result []byte) { | |||
fullblocks := len(data) / 11 | |||
for i := 0; i < fullblocks; i++ { // process partial block | |||
result = append(result, decodeChunk(data[i*11:(i+1)*11])...) | |||
} | |||
if len(data)%11 > 0 { // process last partial block | |||
result = append(result, decodeChunk(data[fullblocks*11:])...) | |||
} | |||
return | |||
} |
@@ -0,0 +1,90 @@ | |||
RESEARCH LICENSE | |||
Version 1.1.2 | |||
I. DEFINITIONS. | |||
"Licensee " means You and any other party that has entered into and has in effect a version of this License. | |||
โLicensorโ means DERO PROJECT(GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8) and its successors and assignees. | |||
"Modifications" means any (a) change or addition to the Technology or (b) new source or object code implementing any portion of the Technology. | |||
"Research Use" means research, evaluation, or development for the purpose of advancing knowledge, teaching, learning, or customizing the Technology for personal use. Research Use expressly excludes use or distribution for direct or indirect commercial (including strategic) gain or advantage. | |||
"Technology" means the source code, object code and specifications of the technology made available by Licensor pursuant to this License. | |||
"Technology Site" means the website designated by Licensor for accessing the Technology. | |||
"You" means the individual executing this License or the legal entity or entities represented by the individual executing this License. | |||
II. PURPOSE. | |||
Licensor is licensing the Technology under this Research License (the "License") to promote research, education, innovation, and development using the Technology. | |||
COMMERCIAL USE AND DISTRIBUTION OF TECHNOLOGY AND MODIFICATIONS IS PERMITTED ONLY UNDER AN APPROPRIATE COMMERCIAL USE LICENSE AVAILABLE FROM LICENSOR AT <url>. | |||
III. RESEARCH USE RIGHTS. | |||
A. Subject to the conditions contained herein, Licensor grants to You a non-exclusive, non-transferable, worldwide, and royalty-free license to do the following for Your Research Use only: | |||
1. reproduce, create Modifications of, and use the Technology alone, or with Modifications; | |||
2. share source code of the Technology alone, or with Modifications, with other Licensees; | |||
3. distribute object code of the Technology, alone, or with Modifications, to any third parties for Research Use only, under a license of Your choice that is consistent with this License; and | |||
4. publish papers and books discussing the Technology which may include relevant excerpts that do not in the aggregate constitute a significant portion of the Technology. | |||
B. Residual Rights. You may use any information in intangible form that you remember after accessing the Technology, except when such use violates Licensor's copyrights or patent rights. | |||
C. No Implied Licenses. Other than the rights granted herein, Licensor retains all rights, title, and interest in Technology , and You retain all rights, title, and interest in Your Modifications and associated specifications, subject to the terms of this License. | |||
D. Open Source Licenses. Portions of the Technology may be provided with notices and open source licenses from open source communities and third parties that govern the use of those portions, and any licenses granted hereunder do not alter any rights and obligations you may have under such open source licenses, however, the disclaimer of warranty and limitation of liability provisions in this License will apply to all Technology in this distribution. | |||
IV. INTELLECTUAL PROPERTY REQUIREMENTS | |||
As a condition to Your License, You agree to comply with the following restrictions and responsibilities: | |||
A. License and Copyright Notices. You must include a copy of this License in a Readme file for any Technology or Modifications you distribute. You must also include the following statement, "Use and distribution of this technology is subject to the Java Research License included herein", (a) once prominently in the source code tree and/or specifications for Your source code distributions, and (b) once in the same file as Your copyright or proprietary notices for Your binary code distributions. You must cause any files containing Your Modification to carry prominent notice stating that You changed the files. You must not remove or alter any copyright or other proprietary notices in the Technology. | |||
B. Licensee Exchanges. Any Technology and Modifications You receive from any Licensee are governed by this License. | |||
V. GENERAL TERMS. | |||
A. Disclaimer Of Warranties. | |||
TECHNOLOGY IS PROVIDED "AS IS", WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT ANY SUCH TECHNOLOGY IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING OF THIRD PARTY RIGHTS. YOU AGREE THAT YOU BEAR THE ENTIRE RISK IN CONNECTION WITH YOUR USE AND DISTRIBUTION OF ANY AND ALL TECHNOLOGY UNDER THIS LICENSE. | |||
B. Infringement; Limitation Of Liability. | |||
1. If any portion of, or functionality implemented by, the Technology becomes the subject of a claim or threatened claim of infringement ("Affected Materials"), Licensor may, in its unrestricted discretion, suspend Your rights to use and distribute the Affected Materials under this License. Such suspension of rights will be effective immediately upon Licensor's posting of notice of suspension on the Technology Site. | |||
2. IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES IN CONNECTION WITH OR ARISING OUT OF THIS LICENSE (INCLUDING, WITHOUT LIMITATION, LOSS OF PROFITS, USE, DATA, OR ECONOMIC ADVANTAGE OF ANY SORT), HOWEVER IT ARISES AND ON ANY THEORY OF LIABILITY (including negligence), WHETHER OR NOT LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. LIABILITY UNDER THIS SECTION V.B.2 SHALL BE SO LIMITED AND EXCLUDED, NOTWITHSTANDING FAILURE OF THE ESSENTIAL PURPOSE OF ANY REMEDY. | |||
C. Termination. | |||
1. You may terminate this License at any time by notifying Licensor in writing. | |||
2. All Your rights will terminate under this License if You fail to comply with any of its material terms or conditions and do not cure such failure within thirty (30) days after becoming aware of such noncompliance. | |||
3. Upon termination, You must discontinue all uses and distribution of the Technology , and all provisions of this Section V shall survive termination. | |||
D. Miscellaneous. | |||
1. Trademark. You agree to comply with Licensor's Trademark & Logo Usage Requirements, if any and as modified from time to time, available at the Technology Site. Except as expressly provided in this License, You are granted no rights in or to any Licensor's trademarks now or hereafter used or licensed by Licensor. | |||
2. Integration. This License represents the complete agreement of the parties concerning the subject matter hereof. | |||
3. Severability. If any provision of this License is held unenforceable, such provision shall be reformed to the extent necessary to make it enforceable unless to do so would defeat the intent of the parties, in which case, this License shall terminate. | |||
4. Governing Law. This License is governed by the laws of the United States and the State of California, as applied to contracts entered into and performed in California between California residents. In no event shall this License be construed against the drafter. | |||
5. Export Control. You agree to comply with the U.S. export controlsand trade laws of other countries that apply to Technology and Modifications. | |||
READ ALL THE TERMS OF THIS LICENSE CAREFULLY BEFORE ACCEPTING. | |||
BY CLICKING ON THE YES BUTTON BELOW OR USING THE TECHNOLOGY, YOU ARE ACCEPTING AND AGREEING TO ABIDE BY THE TERMS AND CONDITIONS OF THIS LICENSE. YOU MUST BE AT LEAST 18 YEARS OF AGE AND OTHERWISE COMPETENT TO ENTER INTO CONTRACTS. | |||
IF YOU DO NOT MEET THESE CRITERIA, OR YOU DO NOT AGREE TO ANY OF THE TERMS OF THIS LICENSE, DO NOT USE THIS SOFTWARE IN ANY FORM. | |||
@@ -0,0 +1,401 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package block | |||
import "fmt" | |||
//import "sort" | |||
import "bytes" | |||
import "runtime/debug" | |||
import "encoding/hex" | |||
import "encoding/binary" | |||
import "github.com/ebfe/keccak" | |||
import "github.com/romana/rlog" | |||
import "github.com/deroproject/derosuite/crypto" | |||
//import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/cryptonight" | |||
import "github.com/deroproject/derosuite/transaction" | |||
// these are defined in file | |||
//https://github.com/monero-project/monero/src/cryptonote_basic/cryptonote_basic.h | |||
type Block_Header struct { | |||
Major_Version uint64 `json:"major_version"` | |||
Minor_Version uint64 `json:"minor_version"` | |||
Timestamp uint64 `json:"timestamp"` | |||
Nonce uint32 `json:"nonce"` // TODO make nonce 32 byte array for infinite work capacity | |||
ExtraNonce [32]byte `json:"-"` | |||
Miner_TX transaction.Transaction `json:"miner_tx"` | |||
} | |||
type Block struct { | |||
Block_Header | |||
Proof [32]byte `json:"-"` // Reserved for future | |||
Tips []crypto.Hash `json:"tips"` | |||
Tx_hashes []crypto.Hash `json:"tx_hashes"` | |||
} | |||
// we process incoming blocks in this format | |||
type Complete_Block struct { | |||
Bl *Block | |||
Txs []*transaction.Transaction | |||
} | |||
// see spec here https://cryptonote.org/cns/cns003.txt | |||
// this function gets the block identifier hash | |||
// this has been simplified and varint length has been removed | |||
func (bl *Block) GetHash() (hash crypto.Hash) { | |||
long_header := bl.GetBlockWork() | |||
// keccak hash of this above blob, gives the block id | |||
return crypto.Keccak256(long_header) | |||
} | |||
// converts a block, into a getwork style work, ready for either submitting the block | |||
// or doing Pow Calculations | |||
func (bl *Block) GetBlockWork() []byte { | |||
var buf []byte // bitcoin/litecoin getworks are 80 bytes | |||
var scratch [8]byte | |||
buf = append(buf, []byte{byte(bl.Major_Version), byte(bl.Minor_Version), 0, 0, 0, 0, 0}...) // 0 first 7 bytes are version in little endia format | |||
binary.LittleEndian.PutUint32(buf[2:6], uint32(bl.Timestamp)) | |||
header_hash := crypto.Keccak256(bl.getserializedheaderforwork()) // 0 + 7 | |||
buf = append(buf, header_hash[:]...) // 0 + 7 + 32 = 39 | |||
binary.LittleEndian.PutUint32(scratch[0:4], bl.Nonce) // check whether it needs to be big endian | |||
buf = append(buf, scratch[:4]...) // 0 + 7 + 32 + 4 = 43 | |||
// next place the ExtraNonce | |||
buf = append(buf, bl.ExtraNonce[:]...) // total 7 + 32 + 4 + 32 | |||
buf = append(buf, 0) // total 7 + 32 + 4 + 32 + 1 = 76 | |||
if len(buf) != 76 { | |||
panic(fmt.Sprintf("Getwork not equal to 76 bytes actual %d", len(buf))) | |||
} | |||
return buf | |||
} | |||
// copy the nonce and the extra nonce from the getwork to the block | |||
func (bl *Block) CopyNonceFromBlockWork(work []byte) (err error) { | |||
if len(work) < 74 { | |||
return fmt.Errorf("work buffer is Invalid") | |||
} | |||
bl.Timestamp = uint64(binary.LittleEndian.Uint32(work[2:])) | |||
bl.Nonce = binary.LittleEndian.Uint32(work[7+32:]) | |||
copy(bl.ExtraNonce[:], work[7+32+4:75]) | |||
return | |||
} | |||
// copy the nonce and the extra nonce from the getwork to the block | |||
func (bl *Block) SetExtraNonce(extranonce []byte) (err error) { | |||
if len(extranonce) == 0 { | |||
return fmt.Errorf("extra nonce is invalid") | |||
} | |||
max := len(extranonce) | |||
if max > 32 { | |||
max = 32 | |||
} | |||
copy(bl.ExtraNonce[:], extranonce[0:max]) | |||
return | |||
} | |||
// clear extra nonce | |||
func (bl *Block) ClearExtraNonce() { | |||
for i := range bl.ExtraNonce { | |||
bl.ExtraNonce[i] = 0 | |||
} | |||
} | |||
// clear nonce | |||
func (bl *Block) ClearNonce() { | |||
bl.Nonce = 0 | |||
} | |||
// Get PoW hash , this is very slow function | |||
func (bl *Block) GetPoWHash() (hash crypto.Hash) { | |||
long_header := bl.GetBlockWork() | |||
rlog.Tracef(9, "longheader %x\n", long_header) | |||
tmphash := cryptonight.SlowHash(long_header) | |||
// tmphash := crypto.Scrypt_1024_1_1_256(long_header) | |||
copy(hash[:], tmphash[:32]) | |||
return | |||
} | |||
// serialize block header for calculating PoW | |||
func (bl *Block) getserializedheaderforwork() []byte { | |||
var serialised bytes.Buffer | |||
buf := make([]byte, binary.MaxVarintLen64) | |||
n := binary.PutUvarint(buf, uint64(bl.Major_Version)) | |||
serialised.Write(buf[:n]) | |||
n = binary.PutUvarint(buf, uint64(bl.Minor_Version)) | |||
serialised.Write(buf[:n]) | |||
// it is placed in pow | |||
//n = binary.PutUvarint(buf, bl.Timestamp) | |||
//serialised.Write(buf[:n]) | |||
// write miner tx | |||
serialised.Write(bl.Miner_TX.Serialize()) | |||
// write tips,, merkle tree should be replaced with something faster | |||
tips_treehash := bl.GetTipsHash() | |||
n = binary.PutUvarint(buf, uint64(len(tips_treehash))) | |||
serialised.Write(buf[:n]) | |||
serialised.Write(tips_treehash[:]) // actual tips hash | |||
tx_treehash := bl.GetTXSHash() // hash of all transactions | |||
n = binary.PutUvarint(buf, uint64(len(bl.Tx_hashes))) // count of all transactions | |||
serialised.Write(buf[:n]) | |||
serialised.Write(tx_treehash[:]) // actual transactions hash | |||
return serialised.Bytes() | |||
} | |||
// serialize block header | |||
func (bl *Block) SerializeHeader() []byte { | |||
var serialised bytes.Buffer | |||
buf := make([]byte, binary.MaxVarintLen64) | |||
n := binary.PutUvarint(buf, uint64(bl.Major_Version)) | |||
serialised.Write(buf[:n]) | |||
n = binary.PutUvarint(buf, uint64(bl.Minor_Version)) | |||
serialised.Write(buf[:n]) | |||
n = binary.PutUvarint(buf, bl.Timestamp) | |||
serialised.Write(buf[:n]) | |||
binary.LittleEndian.PutUint32(buf[0:8], bl.Nonce) // check whether it needs to be big endian | |||
serialised.Write(buf[:4]) | |||
serialised.Write(bl.ExtraNonce[:]) | |||
// write miner address | |||
serialised.Write(bl.Miner_TX.Serialize()) | |||
return serialised.Bytes() | |||
} | |||
// serialize entire block ( block_header + miner_tx + tx_list ) | |||
func (bl *Block) Serialize() []byte { | |||
var serialized bytes.Buffer | |||
buf := make([]byte, binary.MaxVarintLen64) | |||
header := bl.SerializeHeader() | |||
serialized.Write(header) | |||
serialized.Write(bl.Proof[:]) // write proof NOT implemented | |||
// miner tx should always be coinbase | |||
//minex_tx := bl.Miner_tx.Serialize() | |||
//serialized.Write(minex_tx) | |||
n := binary.PutUvarint(buf, uint64(len(bl.Tips))) | |||
serialized.Write(buf[:n]) | |||
for _, hash := range bl.Tips { | |||
serialized.Write(hash[:]) | |||
} | |||
//fmt.Printf("serializing tx hashes %d\n", len(bl.Tx_hashes)) | |||
n = binary.PutUvarint(buf, uint64(len(bl.Tx_hashes))) | |||
serialized.Write(buf[:n]) | |||
for _, hash := range bl.Tx_hashes { | |||
serialized.Write(hash[:]) | |||
} | |||
return serialized.Bytes() | |||
} | |||
// get block transactions tree hash | |||
func (bl *Block) GetTipsHash() (result crypto.Hash) { | |||
/*if len(bl.Tips) == 0 { // case for genesis block | |||
panic("Block does NOT refer any tips") | |||
}*/ | |||
// add all the remaining hashes | |||
h := keccak.New256() | |||
for i := range bl.Tips { | |||
h.Write(bl.Tips[i][:]) | |||
} | |||
r := h.Sum(nil) | |||
copy(result[:], r) | |||
return | |||
} | |||
// get block transactions | |||
// we have discarded the merkle tree and have shifted to a plain version | |||
func (bl *Block) GetTXSHash() (result crypto.Hash) { | |||
h := keccak.New256() | |||
for i := range bl.Tx_hashes { | |||
h.Write(bl.Tx_hashes[i][:]) | |||
} | |||
r := h.Sum(nil) | |||
copy(result[:], r) | |||
return | |||
} | |||
// only parses header | |||
func (bl *Block) DeserializeHeader(buf []byte) (err error) { | |||
done := 0 | |||
bl.Major_Version, done = binary.Uvarint(buf) | |||
if done <= 0 { | |||
return fmt.Errorf("Invalid Major Version in Block\n") | |||
} | |||
buf = buf[done:] | |||
bl.Minor_Version, done = binary.Uvarint(buf) | |||
if done <= 0 { | |||
return fmt.Errorf("Invalid Minor Version in Block\n") | |||
} | |||
buf = buf[done:] | |||
bl.Timestamp, done = binary.Uvarint(buf) | |||
if done <= 0 { | |||
return fmt.Errorf("Invalid Timestamp in Block\n") | |||
} | |||
buf = buf[done:] | |||
//copy(bl.Prev_Hash[:], buf[:32]) // hash is always 32 byte | |||
//buf = buf[32:] | |||
bl.Nonce = binary.LittleEndian.Uint32(buf) | |||
buf = buf[4:] | |||
copy(bl.ExtraNonce[:], buf[0:32]) | |||
buf = buf[32:] | |||
// parse miner tx | |||
err = bl.Miner_TX.DeserializeHeader(buf) | |||
if err != nil { | |||
return err | |||
} | |||
return | |||
} | |||
//parse entire block completely | |||
func (bl *Block) Deserialize(buf []byte) (err error) { | |||
done := 0 | |||
defer func() { | |||
if r := recover(); r != nil { | |||
fmt.Printf("Panic while deserialising block, block hex_dump below to make a testcase/debug\n") | |||
fmt.Printf("%s\n", hex.EncodeToString(buf)) | |||
fmt.Printf("Recovered while parsing block, Stack trace below block_hash ") | |||
fmt.Printf("Stack trace \n%s", debug.Stack()) | |||
err = fmt.Errorf("Invalid Block") | |||
return | |||
} | |||
}() | |||
err = bl.DeserializeHeader(buf) | |||
if err != nil { | |||
return fmt.Errorf("Block Header could not be parsed\n") | |||
} | |||
buf = buf[len(bl.SerializeHeader()):] // skup number of bytes processed | |||
// read 32 byte proof | |||
copy(bl.Proof[:], buf[0:32]) | |||
buf = buf[32:] | |||
// header finished here | |||
// read and parse transaction | |||
/*err = bl.Miner_tx.DeserializeHeader(buf) | |||
if err != nil { | |||
return fmt.Errorf("Cannot parse miner TX %x", buf) | |||
} | |||
// if tx was parse, make sure it's coin base | |||
if len(bl.Miner_tx.Vin) != 1 || bl.Miner_tx.Vin[0].(transaction.Txin_gen).Height > config.MAX_CHAIN_HEIGHT { | |||
// serialize transaction again to get the tx size, so as parsing could continue | |||
return fmt.Errorf("Invalid Miner TX") | |||
} | |||
miner_tx_serialized_size := bl.Miner_tx.Serialize() | |||
buf = buf[len(miner_tx_serialized_size):] | |||
*/ | |||
tips_count, done := binary.Uvarint(buf) | |||
if done <= 0 || done > 1 { | |||
return fmt.Errorf("Invalid Tips count in Block\n") | |||
} | |||
buf = buf[done:] | |||
// remember first tx is merkle root | |||
for i := uint64(0); i < tips_count; i++ { | |||
//fmt.Printf("Parsing transaction hash %d tx_count %d\n", i, tx_count) | |||
var h crypto.Hash | |||
copy(h[:], buf[:32]) | |||
buf = buf[32:] | |||
bl.Tips = append(bl.Tips, h) | |||
} | |||
//fmt.Printf("miner tx %x\n", miner_tx_serialized_size) | |||
// read number of transactions | |||
tx_count, done := binary.Uvarint(buf) | |||
if done <= 0 { | |||
return fmt.Errorf("Invalid Tx count in Block\n") | |||
} | |||
buf = buf[done:] | |||
// remember first tx is merkle root | |||
for i := uint64(0); i < tx_count; i++ { | |||
//fmt.Printf("Parsing transaction hash %d tx_count %d\n", i, tx_count) | |||
var h crypto.Hash | |||
copy(h[:], buf[:32]) | |||
buf = buf[32:] | |||
bl.Tx_hashes = append(bl.Tx_hashes, h) | |||
} | |||
//fmt.Printf("%d member in tx hashes \n",len(bl.Tx_hashes)) | |||
return | |||
} |
@@ -0,0 +1,107 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package blockchain | |||
import "fmt" | |||
import "encoding/hex" | |||
import "github.com/deroproject/derosuite/block" | |||
// this file only contains an altchain, 13 long | |||
// which can be used to test out consensus on live data in house | |||
var block_16996 []byte | |||
var block_16997 []byte | |||
var block_16998 []byte | |||
var block_16999 []byte | |||
var block_17000 []byte | |||
var block_17001 []byte | |||
var block_17002 []byte | |||
var block_17003 []byte | |||
var block_17004 []byte | |||
var block_17005 []byte | |||
var block_17006 []byte | |||
var block_17007 []byte | |||
var block_17008 []byte | |||
func init() { | |||
block_16996, _ = hex.DecodeString("06069dacd3d20516417000452bb3c27c028024a1a21b2d8264a13967cc2b070563b7cb2ecc8236240215db02a0850101ffe484010192ca908deef30602b7840aca58a897165d0c4c90a6e1519d635808f5f32d0dfd8cec545751f9719a2b0185ab9544cf529130c7557fa1a7d3ebc0a25f832ca909bca1e67ca1fb38b472fe02080000000007472ac70000") | |||
block_16997, _ = hex.DecodeString("0606e1acd3d2051ae49ffd0caa6ffb6dc5617a06ae75e7d140303d69e06f4b6b0dcc4bc98383bc0fb1aa6002a1850101ffe5840101dd91c1f1edf30602ec337478b685134eff525f3cfbf18dd46de2824fa71a2b822d855376ec04b7f82b01f6f9bcac1f8bc3358c0279588a46433e1fe6a11e97eaaebfaee98dff85a621a102080000000001f682740000") | |||
block_16998, _ = hex.DecodeString("0606c8b2d3d20578581a7ea3a71082ead85cfde06ebb2a4d7bbfcfef9a0fe69e373e78b807fa7f9662013d02a2850101ffe6840101def3eaad9ba00702bb5bb6f749afdd7d64d8b3b4fa2b8a44c77bf637d0c13d3a994b1d269d8780f82b013eeb27eeff0bd10d40f5892504ec95d81399d150cefa504a0fbacfe6fdc8a563020800000000a0472ac70017abda0ac60520cf99e8b28612349ae639fcbdcc4b1ee256bd064660e96029ba63b0450e0e92ee7af62ca755e2f0522e68a4c11497c1179e09dad0a807729455abc27d43eefa50e1714eb0714e45742c7c6c4dd718b494d3290177dd18172a5acc03d87bf62b5c7d6980a78a238061894f2baf3e3929dc006abcd3622f80adc7dcd900d779234f61b29f6f98ba0956a08082607d6c95ead01c252a5086b413a9fd3a0dd65e7e2005395c69a0a676af4048a69e4191b5948d1cae9cb548ef8bc79dd8e247ed59b2b67e7ff1d7129de06038c388bc55581585b178c440eb9d8e60ab843859096066f80ca797d71db0b481d27f64791dc4cfc621ab462d455c94f7424ab37e5a8ca54eca36d5c0dc096cf85b3022f5c5461f704eea1b48b625189e13575dc5528ba9321dea609fa0574b36a4225c7c850f6b78ce68b2a6d6f001bf9874400f342178ef174768af48d2f3bab1cf647684315321fa09ee984b18667712a37f8767923e0f43524a27b4744a2a189ab42b0eee3505aad99afa25952a9debf3fb8f643488edc07d19bd4ce931e82405a22f3f65aa2500146eeafe7aa2785e9e25f5dc5283b684e29582242db611927cdb6a33636b916a6923f56afe2233bc6cd9e3fb4c999eda97345ce93f6af87d917a110c24b885e40b1bab0213a3dc13ea61c256f8cae39eda04a7d4f234a4b8a664834135bd01169b5ae91683a0b11e245b7e3ac9088f863f260c9697b420a80b9e1ec0713b230a2ae4b2edb9f8fad5616c670ff266a41b2006fdfbe835682a6f97486c2df19c3a1052202b74e0d65a59c2fada5e48344a33d0b1d97d1b7fd261a3f8226644c8ca8127fd3a4347ae5bd5b09a9bbbfcb1026da1a2ef4521247d53c0d71abcec48f9d6112f6dd43627aa882a53d4f7e97b27e52c57b66eefa55d2e855459fb46b2f273f564f390fa3f005281716c770f50afbbc1946e1516e6bddd2ce0ea826a4a6f433cadfeb962e4b97964737a3bada86e6ec67b36b94873402dbf72fd53f7f7f5c8804ddb82069f41") | |||
block_16999, _ = hex.DecodeString("0606d0c9d3d20503ca43b2dbfefe2b1854c516a4d30a7feeb5386dfe1169c3caf33ec3ff898582ed0300d702a3850101ffe78401019fd4ef8592a007025a5d066ac8f5772be60aad59ac33813937efb7edd090006d83f7b625d56deeb72b012c28df62dfe6eda5c5d3113f8d1f3de463f99937e57369ce44b26580444dbf1b0208000000000cf68274001774149ceb2f51f2b8a71536e1e1ddd57a141cdb19d9dea33bf10b09fd336617b0b0f82f931a8147cdc44dbaa9d95425c9980dcd5ab9065892fbeed204902e339f31ca3214fdecac929eb7a4d09fcd799bbe12c5adda9740fa20e4a58178bf32fa014252ccdfb7f5e97838ec2e142eb7ba77115ad0ce34f875e8d0e7d15a2aaa4ddd07a95dd7b66f7b3354c455b712014acf488051700d91869abd0c386ebb40c8c958b296459577ac81d472c1b7c026cfbf355bf86c603fc98615b8f3ae17d17cb4f8edbbdf0bdaf1f269651ef74c1e653d84ff5c597031a008e58f68a04db944da76a0ee549dbadbf47bffa9d729a7747226496b7e213f0729639eebeb6f48108a82a1ca79591e9efd8c6c020be08b02e76d2ebf61aa3f21b84f90bf2a618b477bb01c4b62bd317b4cf92b846d81f8eee205689e4f084e189f3124e697877f67d857f478803f81c1f8b7b893f3f8af830833600d75c43e61733c648cc4a524b50e32232cf5e0e6d9b5c4e539e3d33578aa9c82b54e549e92b1e04d16f3f9dbd156163b6fca1ce4c1572482f2d7dc16634043a7b828488f0b8e5178ddedab49bba1b6646110f2437e83782f50dcffedc67ea4f59971681a3e0f552de091bebbd2c0be66fd022b64d3c61e450513bb4edd1123ef43b1da771bcd94141b29ca933db89499001acb38098e666a8c8d426692ab16547009db6f55a1badc84ea714fbe9c6d63cbfdba522c4d9bac212fdabce699691c646e50fe77e6b6110174d4ff592de728b309cd842af835b80b5966df29fa10d5341c7c3637922b7dfa7ec00937b17522a0136067fe7823bd1808ff8850556584f39b61cc774871a4ff3adedab05cad0e401308b0e9ecd231a4d50f85bc50babfd3701256c7dfaa5b86f37cbe7dc71ce59eb3fbfc0afc6a80b2a4450673f9a44772eee79df273d1bdd43faf13f813dc222c7c88d371504d721be75332b20e3278afefcdb1b4c5a36aee6ae4a5fd7aec7e4f79daab35affd5f8fa2edbd40b83e761b8d59a74cf87e77944244539b") | |||
block_17000, _ = hex.DecodeString("0606a1cfd3d2050eb61f1b78d810d314769e5e6157bc22894127b5d8e5bc417e99091005a7b8588f81029602a4850101ffe8840101ebccbfbbe5f906023c944822f98c9f59fdef57a196bf1987d6f04f8e0721034f974ceb3e4d88bb2d2b019c25765d6603202013f4a89d8ab60e3149ef064aee4a8feab0f936115a716a5502080000000004f64c0300036c69e35c2acfc877af5d1eaa74c70606dbc0b61d84f7e9d497fffaa1af1b6d169027c337be0ddbe65cbe3e21586915d4f39627a96397a40e445be458ba739200ef54f28c61a031912cd49d1a8c8ef1ccba64e23854dbb3328a2551de2290cfc8") | |||
block_17001, _ = hex.DecodeString("0606f5d7d3d205a39b5f88e39231ddebf80f8023724f9b7ee77dbb81e91f19b96933a8cf118313ac15007902a5850101ffe9840101f1dc8d83edf30602b41caa95b2a8f18f4a776d13b501d9c75690cc8eb08214a2f56ade005667b1c32b01b8ebd18f15c4d2028b057b25561c5802455cb0e8628036448d87f8aa917a866302080000000003472ac70000") | |||
block_17002, _ = hex.DecodeString("060684dbd3d205f63b50e5962bb7fec38a224f09935177a103c20bcd272a0df24c36559bdc21068e8e029502a6850101ffea840101e4a8bee7ecf30602613f808c5bbb29eb77f807aaf7a4f155a40b60c858a1eac744f110f182ff236c2b0179be02b5802845c93eb47dec53c476b3ab6c9d416a098ce0c94a0a108f87b6c102080000000003f64c030000") | |||
block_17003, _ = hex.DecodeString("0606a0ddd3d205f87dd7136998a2e56a963ca1387a9738a98c7aa72a6f8a570f9c71397af383ed76080a1502a7850101ffeb840101c6c7edffe9f506021c41a23fd5a320a69fa4cb7d2ed436ccbab272e00a87a8e5e62773d2ba068af02b01f760a7b6c9ab5c7a93980930048314a0d030453bff3f17d480e2a47db4423d6202080000000002f682740001a3da5b87603312186d940ef790c3cd3d46ae5533a4118b40949d902d3a190583") | |||
block_17004, _ = hex.DecodeString("0606a8dfd3d2058e7a86de29068834e3dd3a498c4717159cceec7b6f0753b65cbf889d564a69823c7c008a02a8850101ffec84010197c39fb0ecf3060235527c1f4ad20b7003a4a714801d5e0fc5c44538256b2c80e4c98a75be7424ed2b01296ce3ef0900a4d99c574f918e11b1e72e536b8f3a69702bf307800b8852037a02080000000002f64c030000") | |||
block_17005, _ = hex.DecodeString("0606c5e1d3d205038e2b878d3c204b8726a4159d8e2c113900a7180015ea30a48eda138ed043c7714e05ec02a9850101ffed840101d691d094ecf306020b9449d7678bc9eeaee5d73f2d56b87e07c7d44172c8b994e009bf2a4c4af6752b01fb004518d60291251a1a576677f9e2bcf5233079c7a0b2b42190b7cb8fb6ff0502080000000002472ac70000") | |||
block_17006, _ = hex.DecodeString("0606d9e7d3d2059249ac65bef9acb1b4375a50d9857627ef9f78961fe8fdd6068621572a174bd61c1e006802aa850101ffee84010183e180f9ebf30602edc679784518be061a918062d7b11544948d091e5f06d389d849156100d47b5e2b01a9128d72db29bc746278350850ba4d12a904dc565a03265c599c30b5b34e921a02080000000004472ac70000") | |||
block_17007, _ = hex.DecodeString("0606a9e9d3d2051d9687780f854ea310bf5d7ea5e756be167fa043d81a58c3a3e602e08e7ad9209929090602ab850101ffef8401019fb1b1ddebf30602c7b8a1da31ed781b3153245337e5c34aab53055ebc64a0de8a7c336af1a233ce2b016cbf39ec1ad5079ec981f8ce5b0e59b2e014199c0476496cf404a1323adb6d4d02080000000001bcd9f60000") | |||
block_17008, _ = hex.DecodeString("0606f3efd3d2056360ac8eba51cf1215461f304635e01935345f7fb7fa0c1ce3263ac131b5cb35ff94049c02ac850101fff0840101aa9fddd9e3f90602a96b487a44e654d507ce0874bf5464b6bc7e6ca41af6616b2e3382a95c6ca0c82b01ba0c32ea6c5ca20178026281d05527d6bb0c55b744df551a7dca1bb836f69cb802080000000012f64c030003c58f0769da85da444823d8d6839b16253df8f09ffdddc13dfdb9a2b6fbc8628e83cbaf489cf66fb1c6b0c1b8999fba800cf9fce5750dbc167e359c9b0dee3fdc1492c83a04df176ebc184492194ebe64191d471f377132dcafb09724b8176b4a") | |||
} | |||
func (chain *Blockchain) Inject_Alt_Chain() { | |||
if chain.Get_Height() < 16997 { | |||
fmt.Printf("cannot inject alt-chain for testing purpose\n") | |||
} | |||
chain.inject_block(block_16996) | |||
/**/ /* chain.inject_block(block_16997) | |||
chain.inject_block(block_16998) | |||
/**/ /* chain.inject_block(block_16999) | |||
chain.inject_block(block_17000) | |||
chain.inject_block(block_17001) | |||
chain.inject_block(block_17002) | |||
chain.inject_block(block_17003) | |||
chain.inject_block(block_17004) | |||
chain.inject_block(block_17005) | |||
chain.inject_block(block_17006) | |||
chain.inject_block(block_17007) | |||
/* chain.inject_block(block_17008) | |||
*/ | |||
} | |||
func (chain *Blockchain) inject_block(x []byte) { | |||
var bl block.Block | |||
if len(x) < 20 { | |||
fmt.Printf("block cannot be injected for sure\n") | |||
return | |||
} | |||
err := bl.Deserialize(x) | |||
if err != nil { | |||
fmt.Printf("cannor deserialize hardcoded block\n") | |||
return | |||
} | |||
//chain.Chain_Add(&bl) | |||
} |
@@ -0,0 +1,124 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package blockchain | |||
/* | |||
import log "github.com/sirupsen/logrus" | |||
import "github.com/deroproject/derosuite/crypto" | |||
import "github.com/deroproject/derosuite/block" | |||
import "github.com/deroproject/derosuite/transaction" | |||
//import "github.com/deroproject/derosuite/blockchain/mempool" | |||
*/ | |||
// DERO blockchain has been designed/developed as a state machine ( single-threaded) | |||
// The state machine cannot change until there is external input | |||
// the blockchain has 2 events as input | |||
// 1) new block | |||
// 2) new transaction | |||
// So, the blockchain just waits for events from 2 sources | |||
// 1) p2p layer ( network did a trasaction or found new block after mining) | |||
// 2) user side ( user did a transaction or found new block after mining) | |||
// the design has been simplified so as smart contracts can be integrated easily | |||
// NOTE that adding a block is an atomic event in DERO blockchain | |||
// | |||
// | |||
// This is the global event handler for block | |||
// any block whether mined locally or via network must be dispatched using this channel | |||
//var Incoming_Block_Channel = make(chan *block.Complete_Block, 512) // upto 500 blocks can be queued | |||
//var Incoming_Transaction_Channel = make(chan *transaction.Transaction, 512) // upto 500 transactions can be queued | |||
/* | |||
// infinite looping function to process incoming block | |||
// below event loops are never terminated, not even while exiting | |||
// but we take the lock of chain, so as state/db cannot be changed | |||
// also note that p2p layer is stopped earlier, so input cannot appear | |||
func (chain *Blockchain) Handle_Block_Event_Loop(){ | |||
for{ | |||
select{ | |||
case <-chain.Exit_Event: | |||
logger.Debugf("Exiting Block event loop") | |||
return | |||
default: | |||
} | |||
select{ | |||
case <-chain.Exit_Event: | |||
logger.Debugf("Exiting Block event loop") | |||
return | |||
case complete_bl := <- Incoming_Block_Channel: | |||
logger.Debugf("Incoming New Block") | |||
func (){ | |||
var blid crypto.Hash | |||
_ = blid | |||
// defer func() { // safety so if anything wrong happens, verification fails | |||
/// if r := recover(); r != nil { | |||
// logger.WithFields( log.Fields{"blid": blid}).Warnf("Recovered while processing incoming block") | |||
// }}() | |||
blid = complete_bl.Bl.GetHash() | |||
chain.add_Complete_Block(complete_bl) | |||
}() | |||
//default: | |||
//case <- Exit_Event: | |||
} | |||
} | |||
} | |||
// infinite looping function to process incoming block | |||
func (chain *Blockchain) Handle_Transaction_Event_Loop(){ | |||
for{ | |||
select { | |||
case <-chain.Exit_Event: | |||
logger.Debugf("Exiting Block event loop") | |||
return | |||
case tx := <- Incoming_Transaction_Channel: | |||
logger.Debugf("Incoming New Transaction") | |||
func() { | |||
var txid crypto.Hash | |||
defer func() { // safety so if anything wrong happens, verification fails | |||
if r := recover(); r != nil { | |||
logger.WithFields( log.Fields{"txid": txid}).Warnf("Recovered while Verifying transaction, failed verification") | |||
//result = false | |||
}}() | |||
txid = tx.GetHash() | |||
}() | |||
// case <- Exit_Event: | |||
} | |||
} | |||
} | |||
*/ |
@@ -0,0 +1,62 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package blockchain | |||
//import "fmt" | |||
import "github.com/deroproject/derosuite/crypto" | |||
import "github.com/deroproject/derosuite/structures" | |||
/* fill up the above structure from the blockchain */ | |||
func (chain *Blockchain) GetBlockHeader(hash crypto.Hash) (result structures.BlockHeader_Print, err error) { | |||
dbtx, err := chain.store.BeginTX(false) | |||
if err != nil { | |||
logger.Warnf("Could NOT add block to chain. Error opening writable TX, err %s", err) | |||
return | |||
} | |||
defer dbtx.Rollback() | |||
bl, err := chain.Load_BL_FROM_ID(dbtx, hash) | |||
if err != nil { | |||
return | |||
} | |||
result.TopoHeight = -1 | |||
if chain.Is_Block_Topological_order(dbtx, hash) { | |||
result.TopoHeight = chain.Load_Block_Topological_order(dbtx, hash) | |||
} | |||
result.Height = chain.Load_Height_for_BL_ID(dbtx, hash) | |||
result.Depth = chain.Get_Height() - result.Height | |||
result.Difficulty = chain.Load_Block_Difficulty(dbtx, hash).String() | |||
result.Hash = hash.String() | |||
result.Major_Version = uint64(bl.Major_Version) | |||
result.Minor_Version = uint64(bl.Minor_Version) | |||
result.Nonce = uint64(bl.Nonce) | |||
result.Orphan_Status = chain.Is_Block_Orphan(hash) | |||
result.SyncBlock = chain.IsBlockSyncBlockHeight(dbtx, hash) | |||
result.Reward = chain.Load_Block_Total_Reward(dbtx, hash) | |||
result.TXCount = int64(len(bl.Tx_hashes)) | |||
for i := range bl.Tips { | |||
result.Tips = append(result.Tips, bl.Tips[i].String()) | |||
} | |||
//result.Prev_Hash = bl.Prev_Hash.String() | |||
result.Timestamp = bl.Timestamp | |||
return | |||
} |
@@ -0,0 +1,33 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package blockchain | |||
// this package identifies the 2nd level caller of this function | |||
// this is done to ensure checks regarding locking etc and to be sure no spuros calls are possible | |||
import "runtime" | |||
func CallerName() string { | |||
pc, _, _, ok := runtime.Caller(1) | |||
details := runtime.FuncForPC(pc) | |||
if ok && details != nil { | |||
//fmt.Printf("called from %s\n", details.Name()) // we should only give last parse after . | |||
return details.Name() | |||
} | |||
return "" | |||
} |
@@ -0,0 +1,23 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package blockchain | |||
import "github.com/deroproject/derosuite/crypto" | |||
// this file contains all the constant | |||
var ZERO_HASH crypto.Hash |
@@ -0,0 +1,125 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package blockchain | |||
import "fmt" | |||
import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/crypto" | |||
import "github.com/deroproject/derosuite/address" | |||
import "github.com/deroproject/derosuite/crypto/ringct" | |||
import "github.com/deroproject/derosuite/transaction" | |||
// this function creates a miner tx, with specific blockreward | |||
// TODO we should consider hardfork version while creating a miner tx | |||
func Create_Miner_TX(hf_version, height, reward uint64, miner_address address.Address, reserve_size int) (tx transaction.Transaction, err error) { | |||
// initialize extra map in empty tx | |||
tx.Extra_map = map[transaction.EXTRA_TAG]interface{}{} | |||
//TODO need to fix hard fork version checks | |||
tx.Version = 2 | |||
tx.Unlock_Time = height + config.MINER_TX_AMOUNT_UNLOCK // miner tx unlocks in this much time | |||
tx.Vin = append(tx.Vin, transaction.Txin_gen{Height: height}) // add input height | |||
// now lets create encrypted keys, so as the miner_address can spend them | |||
tx_secret_key, tx_public_key := crypto.NewKeyPair() // create new tx key pair | |||
//tx_public_key is added to extra and serialized | |||
tx.Extra_map[transaction.TX_PUBLIC_KEY] = *tx_public_key | |||
derivation := crypto.KeyDerivation(&miner_address.ViewKey, tx_secret_key) // keyderivation using miner address view key | |||
index_within_tx := uint64(0) | |||
// this becomes the key within Vout | |||
ehphermal_public_key := derivation.KeyDerivation_To_PublicKey(index_within_tx, miner_address.SpendKey) | |||
// added the amount and key in vout | |||
tx.Vout = append(tx.Vout, transaction.Tx_out{Amount: reward, Target: transaction.Txout_to_key{Key: ehphermal_public_key}}) | |||
// add reserve size if requested | |||
if reserve_size != 0 { | |||
if reserve_size <= 255 { | |||
tx.Extra_map[transaction.TX_EXTRA_NONCE] = make([]byte, reserve_size, reserve_size) | |||
} else { | |||
// give a warning that nonce was requested but could not be created | |||
} | |||
} | |||
tx.Extra = tx.Serialize_Extra() // serialize the extra | |||
// add 0 byte ringct signature | |||
var sig ringct.RctSig | |||
tx.RctSignature = &sig | |||
return | |||
} | |||
// this function creates a miner tx, with specific blockreward | |||
// TODO we should consider hardfork version while creating a miner tx | |||
// even if the hash changes during hard-forks or between , the TX should still be spendable by the owner | |||
// the tx has might change due to serialization changes/ differences, however keyimage will still be the same and | |||
// thus not double spendable | |||
func Create_Miner_TX2(hf_version, height int64, miner_address address.Address) (tx transaction.Transaction, err error) { | |||
// initialize extra map in empty tx | |||
tx.Extra_map = map[transaction.EXTRA_TAG]interface{}{} | |||
//TODO need to fix hard fork version checks | |||
switch { | |||
case hf_version <= 6: | |||
tx.Version = 2 | |||
default: | |||
err = fmt.Errorf("NO such hardfork version") | |||
} | |||
tx.Unlock_Time = uint64(height) + config.MINER_TX_AMOUNT_UNLOCK // miner tx unlocks in this much time | |||
tx.Vin = append(tx.Vin, transaction.Txin_gen{Height: uint64(height)}) // add input height | |||
// now lets create encrypted keys, so as the miner_address can spend them | |||
// but also everyone on planet generates the same key | |||
//tx_secret_key := crypto.Key(seed) | |||
//crypto.ScReduce32(&tx_secret_key) | |||
// tx_public_key := tx_secret_key.PublicKey() | |||
tx_secret_key, tx_public_key := crypto.NewKeyPair() // create new tx key pair | |||
//tx_public_key is added to extra and serialized | |||
tx.Extra_map[transaction.TX_PUBLIC_KEY] = *tx_public_key | |||
derivation := crypto.KeyDerivation(&miner_address.ViewKey, tx_secret_key) // keyderivation using miner address view key | |||
index_within_tx := uint64(0) | |||
// this becomes the key within Vout | |||
ehphermal_public_key := derivation.KeyDerivation_To_PublicKey(index_within_tx, miner_address.SpendKey) | |||
// added the amount and key in vout | |||
tx.Vout = append(tx.Vout, transaction.Tx_out{Amount: 0, Target: transaction.Txout_to_key{Key: ehphermal_public_key}}) | |||
tx.Extra = tx.Serialize_Extra() // serialize the extra | |||
// add 0 byte ringct signature | |||
var sig ringct.RctSig | |||
tx.RctSignature = &sig | |||
return | |||
} |
@@ -0,0 +1,135 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package blockchain | |||
//import "fmt" | |||
import "testing" | |||
import "github.com/deroproject/derosuite/walletapi" | |||
import "github.com/deroproject/derosuite/crypto" | |||
//import "github.com/deroproject/derosuite/address" | |||
import "github.com/deroproject/derosuite/transaction" | |||
// file to test whether the miner tx is created successfully and can be serialized/decoded successfully by the block miner | |||
func Test_Create_Miner_TX(t *testing.T) { | |||
for i := 0; i < 1; i++ { | |||
hf_version := uint64(0) | |||
height := uint64(i) | |||
reward := uint64(i + 1) | |||
account, _ := walletapi.Generate_Keys_From_Random() | |||
miner_address := account.GetAddress() | |||
miner_tx_original, err := Create_Miner_TX(hf_version, height, reward, miner_address, 0) | |||
if err != nil { | |||
t.Fatalf("error creating miner tx, err :%s", err) | |||
} | |||
miner_tx_original_serialized := miner_tx_original.Serialize() | |||
var miner_tx_parsed transaction.Transaction | |||
err = miner_tx_parsed.DeserializeHeader(miner_tx_original_serialized) | |||
if err != nil { | |||
t.Fatalf("error parsing created miner tx, err :%s", err) | |||
} | |||
miner_tx_parsed.Parse_Extra() // parse the extra | |||
if miner_tx_parsed.Vin[0].(transaction.Txin_gen).Height != height { | |||
t.Fatalf("miner tx height mismatch") |