@ -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,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. |
||||
|
|
@ -1,5 +1,20 @@ |
|||||
package blockchain |
|
||||
|
|
||||
|
// 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 "bytes" |
import "bytes" |
||||
import "testing" |
import "testing" |
@ -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,60 @@ |
|||||
|
// 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" |
||||
|
|
||||
|
// this is used to print blockheader for the rpc and the daemon
|
||||
|
type BlockHeader_Print struct { |
||||
|
Depth uint64 `json:"depth"` |
||||
|
Difficulty uint64 `json:"difficulty"` |
||||
|
Hash string `json:"hash"` |
||||
|
Height uint64 `json:"height"` |
||||
|
Major_Version uint64 `json:"major_version"` |
||||
|
Minor_Version uint64 `json:"minor_version"` |
||||
|
Nonce uint64 `json:"nonce"` |
||||
|
Orphan_Status bool `json:"orphan_status"` |
||||
|
Reward uint64 `json:"reward"` |
||||
|
Prev_Hash string `json:"prev_hash"` |
||||
|
Timestamp uint64 `json:"timestamp"` |
||||
|
} |
||||
|
|
||||
|
/* fill up the above structure from the blockchain */ |
||||
|
func (chain *Blockchain) GetBlockHeader(hash crypto.Hash) (result BlockHeader_Print, err error) { |
||||
|
|
||||
|
bl, err := chain.Load_BL_FROM_ID(hash) |
||||
|
if err != nil { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
result.Height = chain.Load_Height_for_BL_ID(hash) |
||||
|
result.Depth = chain.Get_Height() - result.Height - 1 |
||||
|
result.Difficulty = chain.Get_Difficulty_At_Block(hash) |
||||
|
result.Hash = hash.String() |
||||
|
result.Height = chain.Load_Height_for_BL_ID(hash) |
||||
|
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.Reward = chain.Load_Block_Reward(hash) |
||||
|
|
||||
|
result.Prev_Hash = bl.Prev_Hash.String() |
||||
|
result.Timestamp = bl.Timestamp |
||||
|
|
||||
|
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,76 @@ |
|||||
|
// 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/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
|
||||
|
switch { |
||||
|
case hf_version <= 6: |
||||
|
tx.Version = 2 |
||||
|
default: |
||||
|
err = fmt.Errorf("NO such hardfork version") |
||||
|
} |
||||
|
|
||||
|
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 |
||||
|
} |
@ -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") |
||||
|
} |
||||
|
|
||||
|
if miner_tx_parsed.Vout[0].Amount != reward { |
||||
|
t.Fatalf("miner tx reward mismatch") |
||||
|
} |
||||
|
|
||||
|
// check whether we can decode it output
|
||||
|
|
||||
|
public_key := miner_tx_parsed.Extra_map[transaction.TX_PUBLIC_KEY].(crypto.Key) |
||||
|
vout_key := miner_tx_parsed.Vout[0].Target.(transaction.Txout_to_key).Key |
||||
|
index_within_tx := uint64(0) |
||||
|
if !account.Is_Output_Ours(public_key, index_within_tx, vout_key) { |
||||
|
t.Fatalf("miner tx cannot be decrypted by the wallet") |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func Test_Create_Miner_TX_with_extra(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, 60) |
||||
|
|
||||
|
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") |
||||
|
} |
||||
|
|
||||
|
if miner_tx_parsed.Vout[0].Amount != reward { |
||||
|
t.Fatalf("miner tx reward mismatch") |
||||
|
} |
||||
|
|
||||
|
// check whether we can decode it output
|
||||
|
|
||||
|
public_key := miner_tx_parsed.Extra_map[transaction.TX_PUBLIC_KEY].(crypto.Key) |
||||
|
vout_key := miner_tx_parsed.Vout[0].Target.(transaction.Txout_to_key).Key |
||||
|
index_within_tx := uint64(0) |
||||
|
if !account.Is_Output_Ours(public_key, index_within_tx, vout_key) { |
||||
|
t.Fatalf("miner tx cannot be decrypted by the wallet") |
||||
|
} |
||||
|
|
||||
|
extra_data := miner_tx_parsed.Extra_map[transaction.TX_EXTRA_NONCE].([]byte) |
||||
|
|
||||
|
if len(extra_data) != 60 { |
||||
|
t.Fatalf("miner tx extra data mismatch") |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -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,66 @@ |
|||||
|
// 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 inputmaturity |
||||
|
|
||||
|
import "time" |
||||
|
import "github.com/deroproject/derosuite/config" |
||||
|
|
||||
|
//this file implements the logic to detect whether an input is mature or still locked
|
||||
|
//This function is crucial as any bugs can have catastrophic effects
|
||||
|
//this function is used both by the core blockchain and wallet
|
||||
|
//TODO we need to check the edge cases
|
||||
|
func Is_Input_Mature(current_chain_height uint64, input_block_height uint64, locked_to_height uint64, sigtype uint64) bool { |
||||
|
|
||||
|
// current_chain_height must be greater or equal to input height
|
||||
|
if current_chain_height < input_block_height { // wrong cases reject
|
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// all miner txs end up here
|
||||
|
if sigtype == 0 { // miner tx will also always unlock 60 blocks in future
|
||||
|
if current_chain_height >= (input_block_height + config.MINER_TX_AMOUNT_UNLOCK) { |
||||
|
return true |
||||
|
} |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// 99.99 % normal tx cases come here
|
||||
|
if locked_to_height == 0 { // input is not locked, so it must be unlocked in 10 blocks
|
||||
|
if current_chain_height >= (input_block_height + config.NORMAL_TX_AMOUNT_UNLOCK) { |
||||
|
return true |
||||
|
} |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// input_block_height is no longer useful
|
||||
|
|
||||
|
// if we are here input was locked to specific height or time
|
||||
|
if locked_to_height < config.CRYPTONOTE_MAX_BLOCK_NUMBER { // input was locked to specific block height
|
||||
|
if current_chain_height >= locked_to_height { |
||||
|
return true |
||||
|
} |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// anything above LIMIT is time based lock
|
||||
|
// input was locked to specific time in epoch
|
||||
|
if locked_to_height < (uint64(time.Now().UTC().Unix())) { |
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
return false // reject time based locks if not mature
|
||||
|
} |
@ -0,0 +1,144 @@ |
|||||
|
// 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 inputmaturity |
||||
|
|
||||
|
import "testing" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/config" |
||||
|
|
||||
|
//this file implements the logic to detect whether an input is mature or still locked
|
||||
|
//This function is crucial as any bugs can have catastrophic effects
|
||||
|
//this function is used both by the core blockchain and wallet
|
||||
|
//TODO we need to check the edge cases
|
||||
|
func Test_Input_Maturity(t *testing.T) { |
||||
|
tests := []struct { |
||||
|
name string |
||||
|
current_chain_height uint64 |
||||
|
input_block_height uint64 |
||||
|
locked_to_height uint64 |
||||
|
sigtype uint64 |
||||
|
expected bool |
||||
|
}{ |
||||
|
{ |
||||
|
name: "simple test", |
||||
|
current_chain_height: 0, |
||||
|
input_block_height: 1, |
||||
|
locked_to_height: 0, |
||||
|
sigtype: 0, |
||||
|
expected: false, |
||||
|
}, |
||||
|
// miner tx blocks mature in 60 blocks
|
||||
|
{ |
||||
|
name: "miner test 59", |
||||
|
current_chain_height: 59, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: 0, |
||||
|
sigtype: 0, |
||||
|
expected: false, |
||||
|
}, |
||||
|
{ |
||||
|
name: "miner test 60", |
||||
|
current_chain_height: 60, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: 0, |
||||
|
sigtype: 0, |
||||
|
expected: true, |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "miner test 60", // genesis block reward should mature at block 61
|
||||
|
current_chain_height: 61, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: 0, |
||||
|
sigtype: 0, |
||||
|
expected: true, |
||||
|
}, |
||||
|
|
||||
|
// normal tx output matures in 10 blocks
|
||||
|
{ |
||||
|
name: "normal test 9", // reward should mature at block 11
|
||||
|
current_chain_height: 9, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: 0, |
||||
|
sigtype: 1, |
||||
|
expected: false, |
||||
|
}, |
||||
|
{ |
||||
|
name: "normal test 10", //reward should mature at block 10
|
||||
|
current_chain_height: 10, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: 0, |
||||
|
sigtype: 1, |
||||
|
expected: true, |
||||
|
}, |
||||
|
{ |
||||
|
name: "normal test 11", // reward should mature at block 11
|
||||
|
current_chain_height: 11, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: 0, |
||||
|
sigtype: 1, |
||||
|
expected: true, |
||||
|
}, |
||||
|
|
||||
|
// height based lock
|
||||
|
{ |
||||
|
name: "locked_to_height ", // reward should mature at specific block
|
||||
|
current_chain_height: config.CRYPTONOTE_MAX_BLOCK_NUMBER - 1, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: config.CRYPTONOTE_MAX_BLOCK_NUMBER - 1, |
||||
|
sigtype: 1, |
||||
|
expected: true, |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "locked_to_height false", // reward should mature at block 11
|
||||
|
current_chain_height: config.CRYPTONOTE_MAX_BLOCK_NUMBER - 2, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: config.CRYPTONOTE_MAX_BLOCK_NUMBER - 1, |
||||
|
sigtype: 1, |
||||
|
expected: false, |
||||
|
}, |
||||
|
|
||||
|
// time based locked
|
||||
|
|
||||
|
{ |
||||
|
name: "locked_to_time false", |
||||
|
current_chain_height: config.CRYPTONOTE_MAX_BLOCK_NUMBER, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: 15174219710, |
||||
|
sigtype: 1, |
||||
|
expected: false, |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "locked_to_time true", |
||||
|
current_chain_height: config.CRYPTONOTE_MAX_BLOCK_NUMBER, |
||||
|
input_block_height: 0, |
||||
|
locked_to_height: 1517421971, |
||||
|
sigtype: 1, |
||||
|
expected: true, |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
for _, test := range tests { |
||||
|
actual := Is_Input_Mature(test.current_chain_height, test.input_block_height, test.locked_to_height, test.sigtype) |
||||
|
if actual != test.expected { |
||||
|
t.Fatalf("Input Maturity testing failed name %s actual %v expected %v", test.name, actual, test.expected) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
// 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 "sort" |
||||
|
|
||||
|
type uint64arr []uint64 |
||||
|
|
||||
|
func (a uint64arr) Len() int { return len(a) } |
||||
|
func (a uint64arr) Swap(i, j int) { a[i], a[j] = a[j], a[i] } |
||||
|
func (a uint64arr) Less(i, j int) bool { return a[i] < a[j] } |
||||
|
|
||||
|
// Median gets the median number in a slice of uint64 numbers
|
||||
|
// this function is used in so many checks that it should have unit tests for sure
|
||||
|
// NOTE: it will the input array
|
||||
|
|
||||
|
func Median(inputs []uint64) (median uint64) { |
||||
|
|
||||
|
// Start by sorting
|
||||
|
sort.Sort(uint64arr(inputs)) |
||||
|
|
||||
|
// No math is needed if there are no numbers
|
||||
|
// For even numbers we add the two middle numbers
|
||||
|
// and divide by two using the mean function above
|
||||
|
// For odd numbers we just use the middle number
|
||||
|
l := len(inputs) |
||||
|
if l == 0 { |
||||
|
return 0 |
||||
|
} else if l%2 == 0 { |
||||
|
median = (inputs[(l/2)-1] + inputs[(l/2)]) / 2 |
||||
|
} else { |
||||
|
median = inputs[l/2] |
||||
|
} |
||||
|
|
||||
|
return median |
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
// 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 "testing" |
||||
|
|
||||
|
// these tests have been taken from the test_math.h from epee tests
|
||||
|
func Test_Median(t *testing.T) { |
||||
|
|
||||
|
{ // test with 0 elements
|
||||
|
var array []uint64 |
||||
|
if Median(array) != 0 { |
||||
|
t.Errorf("Testing failed\n") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
{ // test with 1 element
|
||||
|
array := []uint64{1} |
||||
|
if Median(array) != 1 { |
||||
|
t.Errorf("Testing failed\n") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
{ // test with 2 element
|
||||
|
array := []uint64{1, 10} |
||||
|
if Median(array) != 5 { |
||||
|
t.Errorf("Testing failed\n") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
{ // test with 3 element
|
||||
|
array := []uint64{0, 9, 3} |
||||
|
if Median(array) != 3 { |
||||
|
t.Errorf("Testing failed\n") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
{ // test with 4 element
|
||||
|
array := []uint64{77, 9, 22, 60} |
||||
|
if Median(array) != 41 { |
||||
|
t.Errorf("Testing failed\n") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
{ // test with 5 element
|
||||
|
array := []uint64{77, 9, 22, 60, 11} |
||||
|
if Median(array) != 22 { |
||||
|
t.Errorf("Testing failed\n") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -1,97 +0,0 @@ |
|||||
package blockchain |
|
||||
|
|
||||
|
|
||||
import "sync" |
|
||||
import "time" |
|
||||
import "sync/atomic" |
|
||||
|
|
||||
import log "github.com/sirupsen/logrus" |
|
||||
|
|
||||
import "github.com/deroproject/derosuite/globals" |
|
||||
import "github.com/deroproject/derosuite/crypto" |
|
||||
|
|
||||
|
|
||||
|
|
||||
// at this point in time, this is an ultrafast written mempool,
|
|
||||
// it will not scale for more than 10000 transactions but is good enough for now
|
|
||||
// we can always come back and rewrite it
|
|
||||
type Mempool struct { |
|
||||
txs map[crypto.Hash]mempool_object |
|
||||
|
|
||||
// global variable , but don't see it utilisation here except fot tx verification
|
|
||||
chain *Blockchain |
|
||||
|
|
||||
sync.Mutex |
|
||||
} |
|
||||
|
|
||||
type mempool_object struct { |
|
||||
Tx *Transaction |
|
||||
Added uint64 |
|
||||
Reason int // why is the tx in the mempool
|
|
||||
} |
|
||||
|
|
||||
var loggerpool *log.Entry |
|
||||
|
|
||||
func Init_Mempool(params map[string]interface{}) (*Mempool, error) { |
|
||||
var mempool Mempool |
|
||||
//mempool.chain = params["chain"].(*Blockchain)
|
|
||||
|
|
||||
loggerpool = globals.Logger.WithFields(log.Fields{"com": "POOL"}) // all components must use this logger
|
|
||||
loggerpool.Infof("Mempool started") |
|
||||
atomic.AddUint32(&globals.Subsystem_Active, 1) // increment subsystem
|
|
||||
|
|
||||
//TODO load any trasactions saved at previous exit
|
|
||||
|
|
||||
return &mempool, nil |
|
||||
} |
|
||||
|
|
||||
func (pool *Mempool) Shutdown() { |
|
||||
//TODO save mempool tx somewhere
|
|
||||
loggerpool.Infof("Mempool stopped") |
|
||||
atomic.AddUint32(&globals.Subsystem_Active, ^uint32(0)) // this decrement 1 fom subsystem
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
func (pool *Mempool) Mempool_Add_TX(tx *Transaction, Reason int) { |
|
||||
pool.Lock() |
|
||||
defer pool.Unlock() |
|
||||
|
|
||||
var object mempool_object |
|
||||
|
|
||||
hash := crypto.Hash(tx.GetHash()) |
|
||||
|
|
||||
// check if tx already exists, skip it
|
|
||||
if _, ok := pool.txs[hash]; ok { |
|
||||
loggerpool.Infof("Pool already contains %x, skipping \n", hash) |
|
||||
return |
|
||||
} |
|
||||
object.Tx = tx |
|
||||
object.Reason = Reason |
|
||||
object.Added = uint64(time.Now().Unix()) |
|
||||
|
|
||||
pool.txs[hash] = object |
|
||||
|
|
||||
} |
|
||||
|
|
||||
// delete specific tx from pool
|
|
||||
func (pool *Mempool) Mempool_Delete_TX(crypto.Hash) { |
|
||||
|
|
||||
} |
|
||||
|
|
||||
// get specific tx from mem pool
|
|
||||
func (pool *Mempool) Mempool_Get_TX(txid crypto.Hash) ([]byte, error) { |
|
||||
return nil, nil |
|
||||
} |
|
||||
|
|
||||
// return list of all txs in pool
|
|
||||
func (pool *Mempool) Mempool_List_TX() []crypto.Hash { |
|
||||
pool.Lock() |
|
||||
defer pool.Unlock() |
|
||||
|
|
||||
var list []crypto.Hash |
|
||||
for k, _ := range pool.txs { |
|
||||
list = append(list, k) |
|
||||
} |
|
||||
|
|
||||
return list |
|
||||
} |
|
@ -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,216 @@ |
|||||
|
// 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 mempool |
||||
|
|
||||
|
import "sync" |
||||
|
import "time" |
||||
|
import "sync/atomic" |
||||
|
|
||||
|
import log "github.com/sirupsen/logrus" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/transaction" |
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
import "github.com/deroproject/derosuite/crypto" |
||||
|
|
||||
|
// NOTE: do NOT consider this code as useless, as it is used to avooid double spending attacks within the block
|
||||
|
// let me explain, since we are a state machine, we add block to our blockchain
|
||||
|
// so, if a double spending attack comes, 2 transactions with same inputs, we reject one of them
|
||||
|
// the algo is documented somewhere else which explains the entire process
|
||||
|
|
||||
|
// at this point in time, this is an ultrafast written mempool,
|
||||
|
// it will not scale for more than 10000 transactions but is good enough for now
|
||||
|
// we can always come back and rewrite it
|
||||
|
// NOTE: the pool is not persistant , means closing the daemon will make the mempool empty next restart
|
||||
|
// TODO: make the pool persistant
|
||||
|
type Mempool struct { |
||||
|
txs map[crypto.Hash]mempool_object |
||||
|
key_images map[crypto.Hash]bool // contains key images of all txs
|
||||
|
modified bool // used to monitor whethel mem pool contents have changed,
|
||||
|
|
||||
|
// global variable , but don't see it utilisation here except fot tx verification
|
||||
|
//chain *Blockchain
|
||||
|
|
||||
|
sync.Mutex |
||||
|
} |
||||
|
|
||||
|
type mempool_object struct { |
||||
|
Tx *transaction.Transaction |
||||
|
Added uint64 // time in epoch format
|
||||
|
Reason int // why is the tx in the mempool
|
||||
|
} |
||||
|
|
||||
|
var loggerpool *log.Entry |
||||
|
|
||||
|
func Init_Mempool(params map[string]interface{}) (*Mempool, error) { |
||||
|
var mempool Mempool |
||||
|
//mempool.chain = params["chain"].(*Blockchain)
|
||||
|
|
||||
|
loggerpool = globals.Logger.WithFields(log.Fields{"com": "POOL"}) // all components must use this logger
|
||||
|
loggerpool.Infof("Mempool started") |
||||
|
atomic.AddUint32(&globals.Subsystem_Active, 1) // increment subsystem
|
||||
|
|
||||
|
// initialize maps
|
||||
|
mempool.txs = map[crypto.Hash]mempool_object{} |
||||
|
mempool.key_images = map[crypto.Hash]bool{} |
||||
|
//TODO load any trasactions saved at previous exit
|
||||
|
|
||||
|
return &mempool, nil |
||||
|
} |
||||
|
|
||||
|
// this is created per incoming block and then discarded
|
||||
|
// This does not require shutting down and will be garbage collected automatically
|
||||
|
func Init_Block_Mempool(params map[string]interface{}) (*Mempool, error) { |
||||
|
var mempool Mempool |
||||
|
|
||||
|
// initialize maps
|
||||
|
mempool.txs = map[crypto.Hash]mempool_object{} |
||||
|
mempool.key_images = map[crypto.Hash]bool{} |
||||
|
//TODO load any trasactions saved at previous exit
|
||||
|
|
||||
|
return &mempool, nil |
||||
|
} |
||||
|
|
||||
|
func (pool *Mempool) Shutdown() { |
||||
|
//TODO save mempool tx somewhere
|
||||
|
loggerpool.Infof("Mempool stopped") |
||||
|
atomic.AddUint32(&globals.Subsystem_Active, ^uint32(0)) // this decrement 1 fom subsystem
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
// start pool monitoring for changes for some specific time
|
||||
|
// this is required so as we can add or discard transactions while selecting work for mining
|
||||
|
func (pool *Mempool) Monitor() { |
||||
|
pool.Lock() |
||||
|
pool.modified = false |
||||
|
pool.Unlock() |
||||
|
} |
||||
|
|
||||
|
// return whether pool contents have changed
|
||||
|
func (pool *Mempool) HasChanged() (result bool) { |
||||
|
pool.Lock() |
||||
|
result = pool.modified |
||||
|
pool.Unlock() |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// a tx should only be added to pool after verification is complete
|
||||
|
func (pool *Mempool) Mempool_Add_TX(tx *transaction.Transaction, Reason int) (result bool) { |
||||
|
result = false |
||||
|
pool.Lock() |
||||
|
defer pool.Unlock() |
||||
|
|
||||
|
var object mempool_object |
||||
|
|
||||
|
tx_hash := crypto.Hash(tx.GetHash()) |
||||
|
|
||||
|
// check if tx already exists, skip it
|
||||
|
if _, ok := pool.txs[tx_hash]; ok { |
||||
|
loggerpool.Infof("Pool already contains %s, skipping \n", tx_hash) |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// we should also extract all key images and add them to have multiple pending
|
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
if _, ok := pool.key_images[tx.Vin[i].(transaction.Txin_to_key).K_image]; ok { |
||||
|
loggerpool.WithFields(log.Fields{ |
||||
|
"txid": tx_hash, |
||||
|
"kimage": tx.Vin[i].(transaction.Txin_to_key).K_image, |
||||
|
}).Warnf("TX using inputs which have already been used, Possible Double spend attack rejected") |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// add all the key images to check double spend attack within the pool
|
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
pool.key_images[tx.Vin[i].(transaction.Txin_to_key).K_image] = true // add element to map for next check
|
||||
|
} |
||||
|
|
||||
|
// we are here means we can add it to pool
|
||||
|
object.Tx = tx |
||||
|
object.Reason = Reason |
||||
|
object.Added = uint64(time.Now().Unix()) |
||||
|
|
||||
|
pool.txs[tx_hash] = object |
||||
|
pool.modified = true // pool has been modified
|
||||
|
|
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
// check whether a tx exists in the pool
|
||||
|
func (pool *Mempool) Mempool_TX_Exist(txid crypto.Hash) (result bool) { |
||||
|
pool.Lock() |
||||
|
defer pool.Unlock() |
||||
|
|
||||
|
if _, ok := pool.txs[txid]; ok { |
||||
|
return true |
||||
|
} |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// delete specific tx from pool and return it
|
||||
|
// if nil is returned Tx was not found in pool
|
||||
|
func (pool *Mempool) Mempool_Delete_TX(txid crypto.Hash) (tx *transaction.Transaction) { |
||||
|
pool.Lock() |
||||
|
defer pool.Unlock() |
||||
|
|
||||
|
// check if tx already exists, skip it
|
||||
|
if _, ok := pool.txs[txid]; !ok { |
||||
|
loggerpool.Warnf("Pool does NOT contain %s, returning nil \n", txid) |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// we reached here means, we have the tx remove it from our list, do maintainance cleapup and discard it
|
||||
|
object := pool.txs[txid] |
||||
|
delete(pool.txs, txid) |
||||
|
|
||||
|
// remove all the key images
|
||||
|
for i := 0; i < len(object.Tx.Vin); i++ { |
||||
|
delete(pool.key_images, object.Tx.Vin[i].(transaction.Txin_to_key).K_image) |
||||
|
} |
||||
|
|
||||
|
pool.modified = true // pool has been modified
|
||||
|
return object.Tx // return the tx
|
||||
|
} |
||||
|
|
||||
|
// get specific tx from mem pool without removing it
|
||||
|
func (pool *Mempool) Mempool_Get_TX(txid crypto.Hash) (tx *transaction.Transaction) { |
||||
|
pool.Lock() |
||||
|
defer pool.Unlock() |
||||
|
|
||||
|
if _, ok := pool.txs[txid]; !ok { |
||||
|
//loggerpool.Warnf("Pool does NOT contain %s, returning nil \n", txid)
|
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// we reached here means, we have the tx, return the pointer back
|
||||
|
object := pool.txs[txid] |
||||
|
|
||||
|
return object.Tx |
||||
|
} |
||||
|
|
||||
|
// return list of all txs in pool
|
||||
|
func (pool *Mempool) Mempool_List_TX() []crypto.Hash { |
||||
|
pool.Lock() |
||||
|
defer pool.Unlock() |
||||
|
|
||||
|
var list []crypto.Hash |
||||
|
for k, _ := range pool.txs { |
||||
|
list = append(list, k) |
||||
|
} |
||||
|
|
||||
|
return list |
||||
|
} |
@ -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,12 @@ |
|||||
|
// 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
|
||||
|
|
||||
|
package rpcserver |
||||
|
|
||||
|
import "testing" |
||||
|
|
||||
|
func Test_Part1(t *testing.T) { |
||||
|
|
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
type ( |
||||
|
EchoHandler struct{} |
||||
|
EchoParams struct { |
||||
|
Name string `json:"name"` |
||||
|
} |
||||
|
EchoResult struct { |
||||
|
Message string `json:"message"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func (h EchoHandler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
|
||||
|
var p EchoParams |
||||
|
if err := jsonrpc.Unmarshal(params, &p); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return EchoResult{ |
||||
|
Message: "Hello, " + p.Name, |
||||
|
}, nil |
||||
|
} |
@ -0,0 +1,93 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
// get block template handler not implemented
|
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "context" |
||||
|
import "encoding/hex" |
||||
|
import "encoding/json" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/crypto" |
||||
|
import "github.com/deroproject/derosuite/blockchain" |
||||
|
|
||||
|
type ( |
||||
|
GetBlock_Handler struct{} |
||||
|
GetBlock_Params struct { |
||||
|
Hash string `json:"hash,omitempty"` // Monero Daemon breaks if both are provided
|
||||
|
Height uint64 `json:"height,omitempty"` // Monero Daemon breaks if both are provided
|
||||
|
} // no params
|
||||
|
GetBlock_Result struct { |
||||
|
Blob string `json:"blob"` |
||||
|
Json string `json:"json"` |
||||
|
Block_Header blockchain.BlockHeader_Print `json:"block_header"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
// TODO
|
||||
|
func (h GetBlock_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
var p GetBlock_Params |
||||
|
var hash crypto.Hash |
||||
|
var err error |
||||
|
|
||||
|
if errp := jsonrpc.Unmarshal(params, &p); err != nil { |
||||
|
return nil, errp |
||||
|
} |
||||
|
|
||||
|
if crypto.HashHexToHash(p.Hash) == hash { // user requested using height
|
||||
|
if p.Height >= chain.Get_Height() { |
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
|
||||
|
hash, err = chain.Load_BL_ID_at_Height(p.Height) |
||||
|
if err != nil { // if err return err
|
||||
|
logger.Warnf("User requested %d height block, chain height %d but err occured %s", p.Height, chain.Get_Height(), err) |
||||
|
|
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
} else { |
||||
|
hash = crypto.HashHexToHash(p.Hash) |
||||
|
} |
||||
|
|
||||
|
block_header, err := chain.GetBlockHeader(hash) |
||||
|
if err != nil { // if err return err
|
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
bl, err := chain.Load_BL_FROM_ID(hash) |
||||
|
if err != nil { // if err return err
|
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
|
||||
|
json_encoded_bytes, err := json.Marshal(bl) |
||||
|
if err != nil { // if err return err
|
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
return GetBlock_Result{ // return success
|
||||
|
Block_Header: block_header, |
||||
|
Blob: hex.EncodeToString(bl.Serialize()), |
||||
|
Json: string(json_encoded_bytes), |
||||
|
Status: "OK", |
||||
|
}, nil |
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
// get block template handler not implemented
|
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
type ( |
||||
|
GetBlockTemplate_Handler struct{} |
||||
|
GetBlockTemplate_Params struct { |
||||
|
Wallet_Address string `json:"wallet_address"` |
||||
|
Reserve_size uint64 `json:"reserve_size"` |
||||
|
} |
||||
|
GetBlockTemplate_Result struct { |
||||
|
Blocktemplate_blob string `json:"blocktemplate_blob"` |
||||
|
Difficulty uint64 `json:"difficulty"` |
||||
|
Height uint64 `json:"height"` |
||||
|
Prev_Hash string `json:"prev_hash"` |
||||
|
Reserved_Offset uint64 `json:"reserved_offset"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func (h GetBlockTemplate_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
|
||||
|
var p GetBlockTemplate_Params |
||||
|
if err := jsonrpc.Unmarshal(params, &p); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
// Wallet_Address needs to validated before
|
||||
|
|
||||
|
return GetBlockTemplate_Result{ |
||||
|
Status: "NOT IMPLEMENTED", |
||||
|
}, nil |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
type ( |
||||
|
GetBlockCount_Handler struct{} |
||||
|
GetBlockCount_Params struct { |
||||
|
// NO params
|
||||
|
} |
||||
|
GetBlockCount_Result struct { |
||||
|
Count uint64 `json:"count"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func (h GetBlockCount_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
return GetBlockCount_Result{ |
||||
|
Count: chain.Get_Height() - 1, |
||||
|
Status: "OK", |
||||
|
}, nil |
||||
|
} |
@ -0,0 +1,61 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
// get block template handler not implemented
|
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/crypto" |
||||
|
import "github.com/deroproject/derosuite/blockchain" |
||||
|
|
||||
|
type ( |
||||
|
GetBlockHeaderByHash_Handler struct{} |
||||
|
GetBlockHeaderByHash_Params struct { |
||||
|
Hash string `json:"hash"` |
||||
|
} // no params
|
||||
|
GetBlockHeaderByHash_Result struct { |
||||
|
Block_Header blockchain.BlockHeader_Print `json:"block_header"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func (h GetBlockHeaderByHash_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
var p GetBlockHeaderByHash_Params |
||||
|
if err := jsonrpc.Unmarshal(params, &p); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
hash := crypto.HashHexToHash(p.Hash) |
||||
|
block_header, err := chain.GetBlockHeader(hash) |
||||
|
|
||||
|
if err != nil { // if err return err
|
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
|
||||
|
return GetBlockHeaderByHash_Result{ // return success
|
||||
|
Block_Header: block_header, |
||||
|
Status: "OK", |
||||
|
}, nil |
||||
|
} |
@ -0,0 +1,72 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
// get block template handler not implemented
|
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
//import "github.com/deroproject/derosuite/crypto"
|
||||
|
import "github.com/deroproject/derosuite/blockchain" |
||||
|
|
||||
|
type ( |
||||
|
GetBlockHeaderByHeight_Handler struct{} |
||||
|
GetBlockHeaderByHeight_Params struct { |
||||
|
Height uint64 `json:"height"` |
||||
|
} // no params
|
||||
|
GetBlockHeaderByHeight_Result struct { |
||||
|
Block_Header blockchain.BlockHeader_Print `json:"block_header"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func (h GetBlockHeaderByHeight_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
var p GetBlockHeaderByHeight_Params |
||||
|
if err := jsonrpc.Unmarshal(params, &p); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
if p.Height >= chain.Get_Height() { |
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
|
||||
|
hash, err := chain.Load_BL_ID_at_Height(p.Height) |
||||
|
if err != nil { // if err return err
|
||||
|
logger.Warnf("User requested %d height block, chain height %d but err occured %s", p.Height, chain.Get_Height(), err) |
||||
|
|
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
|
||||
|
block_header, err := chain.GetBlockHeader(hash) |
||||
|
if err != nil { // if err return err
|
||||
|
logger.Warnf("User requested %d height block, chain height %d but err occured %s", p.Height, chain.Get_Height(), err) |
||||
|
|
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
||||
|
|
||||
|
return GetBlockHeaderByHeight_Result{ // return success
|
||||
|
Block_Header: block_header, |
||||
|
Status: "OK", |
||||
|
}, nil |
||||
|
} |
@ -0,0 +1,94 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
// get block template handler not implemented
|
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/config" |
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
|
||||
|
/* |
||||
|
{ |
||||
|
"id": "0", |
||||
|
"jsonrpc": "2.0", |
||||
|
"result": { |
||||
|
"alt_blocks_count": 5, |
||||
|
"difficulty": 972165250, |
||||
|
"grey_peerlist_size": 2280, |
||||
|
"height": 993145, |
||||
|
"incoming_connections_count": 0, |
||||
|
"outgoing_connections_count": 8, |
||||
|
"status": "OK", |
||||
|
"target": 60, |
||||
|
"target_height": 993137, |
||||
|
"testnet": false, |
||||
|
"top_block_hash": "", |
||||
|
"tx_count": 564287, |
||||
|
"tx_pool_size": 45, |
||||
|
"white_peerlist_size": 529 |
||||
|
} |
||||
|
}*/ |
||||
|
type ( |
||||
|
GetInfo_Handler struct{} |
||||
|
GetInfo_Params struct{} // no params
|
||||
|
GetInfo_Result struct { |
||||
|
Alt_Blocks_Count uint64 `json:"alt_blocks_count"` |
||||
|
Difficulty uint64 `json:"difficulty"` |
||||
|
Grey_PeerList_Size uint64 `json:"grey_peerlist_size"` |
||||
|
Height uint64 `json:"height"` |
||||
|
Incoming_connections_count uint64 `json:"incoming_connections_count"` |
||||
|
Outgoing_connections_count uint64 `json:"outgoing_connections_count"` |
||||
|
Target uint64 `json:"target"` |
||||
|
Target_Height uint64 `json:"target_height"` |
||||
|
Testnet bool `json:"testnet"` |
||||
|
Top_block_hash string `json:"top_block_hash"` |
||||
|
Tx_count uint64 `json:"tx_count"` |
||||
|
Tx_pool_size uint64 `json:"tx_pool_size"` |
||||
|
White_peerlist_size uint64 `json:"white_peerlist_size"` |
||||
|
|
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
// TODO
|
||||
|
func (h GetInfo_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
var result GetInfo_Result |
||||
|
|
||||
|
top_id := chain.Get_Top_ID() |
||||
|
result.Difficulty = chain.Get_Difficulty_At_Block(top_id) |
||||
|
result.Height = chain.Get_Height() - 1 |
||||
|
result.Status = "OK" |
||||
|
result.Top_block_hash = top_id.String() |
||||
|
result.Target = config.BLOCK_TIME |
||||
|
result.Target_Height = chain.Get_Height() |
||||
|
result.Tx_pool_size = uint64(len(chain.Mempool.Mempool_List_TX())) |
||||
|
|
||||
|
if globals.Config.Name != config.Mainnet.Name { // anything other than mainnet is testnet at this point in time
|
||||
|
result.Testnet = true |
||||
|
} |
||||
|
|
||||
|
return result, nil |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
// get block template handler not implemented
|
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/blockchain" |
||||
|
|
||||
|
type ( |
||||
|
GetLastBlockHeader_Handler struct{} |
||||
|
GetLastBlockHeader_Params struct{} // no params
|
||||
|
GetLastBlockHeader_Result struct { |
||||
|
Block_Header blockchain.BlockHeader_Print `json:"block_header"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func (h GetLastBlockHeader_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
top_hash := chain.Get_Top_ID() |
||||
|
block_header, _ := chain.GetBlockHeader(top_hash) |
||||
|
|
||||
|
return GetLastBlockHeader_Result{ |
||||
|
Block_Header: block_header, |
||||
|
Status: "OK", |
||||
|
}, nil |
||||
|
} |
@ -0,0 +1,95 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
import "strconv" |
||||
|
import "net/http" |
||||
|
|
||||
|
import "compress/gzip" |
||||
|
|
||||
|
//import "github.com/pierrec/lz4"
|
||||
|
|
||||
|
// serve the outputs in streaming mode
|
||||
|
|
||||
|
// feeds any outputs requested by the server
|
||||
|
func getoutputs(rw http.ResponseWriter, req *http.Request) { |
||||
|
var err error |
||||
|
start := uint64(0) |
||||
|
stop := uint64(0) |
||||
|
|
||||
|
{ // parse start query parameter
|
||||
|
keys, ok := req.URL.Query()["start"] |
||||
|
if !ok || len(keys) < 1 { |
||||
|
//log.Println("Url Param 'key' is missing")
|
||||
|
//return
|
||||
|
} else { |
||||
|
start_string := keys[0] |
||||
|
start, err = strconv.ParseUint(start_string, 10, 64) |
||||
|
if err != nil { |
||||
|
start = 0 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
{ // parse stop query parameter
|
||||
|
keys, ok := req.URL.Query()["stop"] |
||||
|
if !ok || len(keys) < 1 { |
||||
|
|
||||
|
} else { |
||||
|
stop_string := keys[0] |
||||
|
stop, err = strconv.ParseUint(stop_string, 10, 64) |
||||
|
if err != nil { |
||||
|
stop = 0 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// do sanity check of stop first
|
||||
|
top_id := chain.Get_Top_ID() |
||||
|
biggest_output_index := chain.Block_Count_Vout(top_id) + chain.Get_Block_Output_Index(top_id) |
||||
|
|
||||
|
if stop == 0 || stop > biggest_output_index { |
||||
|
stop = biggest_output_index |
||||
|
} |
||||
|
|
||||
|
// feed in atleast 1 index
|
||||
|
if start >= stop { |
||||
|
start = stop - 1 |
||||
|
} |
||||
|
|
||||
|
/* lz4writer := lz4.NewWriter(rw) |
||||
|
lz4writer.HighCompression = true // enable extreme but slow compression
|
||||
|
lz4writer.BlockMaxSize = 256*1024 // small block size to decrease memory consumption
|
||||
|
*/ |
||||
|
gzipwriter := gzip.NewWriter(rw) |
||||
|
defer gzipwriter.Close() |
||||
|
for i := start; i <= stop; i++ { |
||||
|
// load the bytes and send them
|
||||
|
data, err := chain.Read_output_index(i) |
||||
|
if err != nil { |
||||
|
logger.Warnf("err while reading output err: %s\n", err) |
||||
|
break |
||||
|
} |
||||
|
|
||||
|
//
|
||||
|
//rw.Write(data)
|
||||
|
// lz4writer.Write(data)
|
||||
|
gzipwriter.Write(data) |
||||
|
|
||||
|
} |
||||
|
//lz4writer.Flush() // flush any pending data
|
||||
|
} |
@ -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 rpcserver |
||||
|
|
||||
|
import "net/http" |
||||
|
import "encoding/hex" |
||||
|
import "encoding/json" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/crypto" |
||||
|
|
||||
|
// we definitely need to clear up the MESS that has been created by the MONERO project
|
||||
|
// half of their APIs are json rpc and half are http
|
||||
|
// for compatibility reasons, we are implementing theirs ( however we are also providin a json rpc implementation)
|
||||
|
// we should DISCARD the http
|
||||
|
|
||||
|
// NOTE: we have currently not implemented the decode as json parameter
|
||||
|
// it is however on the pending list
|
||||
|
|
||||
|
type ( |
||||
|
GetTransaction_Handler struct{} |
||||
|
GetTransaction_Params struct { |
||||
|
Tx_Hashes []string `json:"txs_hashes"` |
||||
|
Decode uint64 `json:"decode_as_json,omitempty"` // Monero Daemon breaks if this sent
|
||||
|
} // no params
|
||||
|
GetTransaction_Result struct { |
||||
|
Txs_as_hex []string `json:"txs_as_hex"` |
||||
|
Txs_as_json []string `json:"txs_as_json"` |
||||
|
Txs []Tx_Related_Info `json:"txs"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
|
||||
|
Tx_Related_Info struct { |
||||
|
As_Hex string `json:"as_hex"` |
||||
|
As_Json string `json:"as_json"` |
||||
|
Block_Height int64 `json:"block_height"` |
||||
|
In_pool bool `json:"in_pool"` |
||||
|
Output_Indices []uint64 `json:"output_indices"` |
||||
|
Tx_hash string `json:"tx_hash"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func gettransactions(rw http.ResponseWriter, req *http.Request) { |
||||
|
decoder := json.NewDecoder(req.Body) |
||||
|
var p GetTransaction_Params |
||||
|
err := decoder.Decode(&p) |
||||
|
if err != nil { |
||||
|
panic(err) |
||||
|
} |
||||
|
defer req.Body.Close() |
||||
|
|
||||
|
result := gettransactions_fill(p) |
||||
|
//logger.Debugf("Request %+v", p)
|
||||
|
|
||||
|
encoder := json.NewEncoder(rw) |
||||
|
encoder.Encode(result) |
||||
|
} |
||||
|
|
||||
|
// fill up the response
|
||||
|
func gettransactions_fill(p GetTransaction_Params) (result GetTransaction_Result) { |
||||
|
|
||||
|
for i := 0; i < len(p.Tx_Hashes); i++ { |
||||
|
|
||||
|
hash := crypto.HashHexToHash(p.Tx_Hashes[i]) |
||||
|
|
||||
|
// check whether we can get the tx from the pool
|
||||
|
{ |
||||
|
tx := chain.Mempool.Mempool_Get_TX(hash) |
||||
|
if tx != nil { // found the tx in the mempool
|
||||
|
result.Txs_as_hex = append(result.Txs_as_hex, hex.EncodeToString(tx.Serialize())) |
||||
|
|
||||
|
var related Tx_Related_Info |
||||
|
|
||||
|
related.Block_Height = -1 // not mined
|
||||
|
related.In_pool = true |
||||
|
|
||||
|
for i := 0; i < len(tx.Vout); i++ { |
||||
|
related.Output_Indices = append(related.Output_Indices, 0) // till the tx is mined we do not get indices
|
||||
|
} |
||||
|
|
||||
|
result.Txs = append(result.Txs, related) |
||||
|
|
||||
|
continue // no more processing required
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
tx, err := chain.Load_TX_FROM_ID(hash) |
||||
|
if err == nil { |
||||
|
result.Txs_as_hex = append(result.Txs_as_hex, hex.EncodeToString(tx.Serialize())) |
||||
|
var related Tx_Related_Info |
||||
|
|
||||
|
related.Block_Height = int64(chain.Load_TX_Height(hash)) |
||||
|
|
||||
|
index := chain.Find_TX_Output_Index(hash) |
||||
|
|
||||
|
// logger.Infof("TX hash %s height %d",hash, related.Block_Height)
|
||||
|
for i := 0; i < len(tx.Vout); i++ { |
||||
|
related.Output_Indices = append(related.Output_Indices, index+uint64(i)) |
||||
|
} |
||||
|
|
||||
|
result.Txs = append(result.Txs, related) |
||||
|
|
||||
|
} else { // we could not fetch the tx, return an empty string
|
||||
|
result.Txs_as_hex = append(result.Txs_as_hex, "") |
||||
|
result.Status = "TX NOT FOUND" |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
result.Status = "OK" |
||||
|
return |
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
// get GetTxPool handler not implemented
|
||||
|
|
||||
|
import "fmt" |
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
type ( |
||||
|
GetTxPool_Handler struct{} |
||||
|
GetTxPool_Params struct{} // no params
|
||||
|
GetTxPool_Result struct { |
||||
|
Tx_list []string `json:"txs,omitempty"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
// TODO
|
||||
|
func (h GetTxPool_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
var result GetTxPool_Result |
||||
|
|
||||
|
result.Status = "OK" |
||||
|
|
||||
|
pool_list := chain.Mempool.Mempool_List_TX() |
||||
|
for i := range pool_list { |
||||
|
result.Tx_list = append(result.Tx_list, fmt.Sprintf("%s", pool_list[i])) |
||||
|
} |
||||
|
|
||||
|
return result, nil |
||||
|
} |
@ -0,0 +1,55 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
import "fmt" |
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
type ( |
||||
|
On_GetBlockHash_Handler struct{} |
||||
|
On_GetBlockHash_Params struct { |
||||
|
X [1]uint64 |
||||
|
} |
||||
|
On_GetBlockHash_Result struct{} |
||||
|
) |
||||
|
|
||||
|
func (h On_GetBlockHash_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
|
||||
|
var height [1]uint64 |
||||
|
//var result On_GetBlockHash_Result
|
||||
|
if err := jsonrpc.Unmarshal(params, &height); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
if height[0] < chain.Get_Height() { |
||||
|
hash, err := chain.Load_BL_ID_at_Height(height[0]) |
||||
|
if err == nil { |
||||
|
result := fmt.Sprintf("%s", hash) |
||||
|
return result, nil |
||||
|
} else { |
||||
|
logger.Warnf("NOT possible, Could not find block at height %d Chain height %d\n", height[0], chain.Get_Height()) |
||||
|
} |
||||
|
} |
||||
|
// if we reach here some error is here
|
||||
|
return nil, jsonrpc.ErrInvalidParams() |
||||
|
} |
@ -0,0 +1,150 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
import "io" |
||||
|
import "fmt" |
||||
|
import "time" |
||||
|
import "sync" |
||||
|
import "sync/atomic" |
||||
|
|
||||
|
//import "context"
|
||||
|
import "net/http" |
||||
|
|
||||
|
//import "github.com/intel-go/fastjson"
|
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
import log "github.com/sirupsen/logrus" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
import "github.com/deroproject/derosuite/blockchain" |
||||
|
|
||||
|
/* this file implements the rpcserver api, so as wallet and block explorer tools can work without migration */ |
||||
|
|
||||
|
// all components requiring access to blockchain must use , this struct to communicate
|
||||
|
// this structure must be update while mutex
|
||||
|
type RPCServer struct { |
||||
|
Exit_Event chan bool // blockchain is shutting down and we must quit ASAP
|
||||
|
sync.RWMutex |
||||
|
} |
||||
|
|
||||
|
var Exit_In_Progress bool |
||||
|
var chain *blockchain.Blockchain |
||||
|
var logger *log.Entry |
||||
|
|
||||
|
func RPCServer_Start(params map[string]interface{}) (*RPCServer, error) { |
||||
|
|
||||
|
var err error |
||||
|
var r RPCServer |
||||
|
|
||||
|
_ = err |
||||
|
|
||||
|
r.Exit_Event = make(chan bool) |
||||
|
|
||||
|
logger = globals.Logger.WithFields(log.Fields{"com": "RPC"}) // all components must use this logger
|
||||
|
chain = params["chain"].(*blockchain.Blockchain) |
||||
|
|
||||
|
// test whether chain is okay
|
||||
|
if chain.Get_Height() == 0 { |
||||
|
return nil, fmt.Errorf("Chain DOES NOT have genesis block") |
||||
|
} |
||||
|
|
||||
|
go r.Run() |
||||
|
logger.Infof("RPC server started") |
||||
|
atomic.AddUint32(&globals.Subsystem_Active, 1) // increment subsystem
|
||||
|
|
||||
|
return &r, nil |
||||
|
} |
||||
|
|
||||
|
// shutdown the rpc server component
|
||||
|
func (r *RPCServer) RPCServer_Stop() { |
||||
|
Exit_In_Progress = true |
||||
|
close(r.Exit_Event) // send signal to all connections to exit
|
||||
|
// TODO we must wait for connections to kill themselves
|
||||
|
time.Sleep(1 * time.Second) |
||||
|
logger.Infof("RPC Shutdown") |
||||
|
atomic.AddUint32(&globals.Subsystem_Active, ^uint32(0)) // this decrement 1 fom subsystem
|
||||
|
} |
||||
|
|
||||
|
func (r *RPCServer) Run() { |
||||
|
|
||||
|
mr := jsonrpc.NewMethodRepository() |
||||
|
|
||||
|
if err := mr.RegisterMethod("Main.Echo", EchoHandler{}, EchoParams{}, EchoResult{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
// install getblockcount handler
|
||||
|
if err := mr.RegisterMethod("getblockcount", GetBlockCount_Handler{}, GetBlockCount_Params{}, GetBlockCount_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
// install on_getblockhash
|
||||
|
if err := mr.RegisterMethod("on_getblockhash", On_GetBlockHash_Handler{}, On_GetBlockHash_Params{}, On_GetBlockHash_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
// install getblocktemplate handler
|
||||
|
if err := mr.RegisterMethod("getblocktemplate", GetBlockTemplate_Handler{}, GetBlockTemplate_Params{}, GetBlockTemplate_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
// submitblock handler
|
||||
|
if err := mr.RegisterMethod("submitblock", SubmitBlock_Handler{}, SubmitBlock_Params{}, SubmitBlock_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
if err := mr.RegisterMethod("getlastblockheader", GetLastBlockHeader_Handler{}, GetLastBlockHeader_Params{}, GetLastBlockHeader_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
if err := mr.RegisterMethod("getblockheaderbyhash", GetBlockHeaderByHash_Handler{}, GetBlockHeaderByHash_Params{}, GetBlockHeaderByHash_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
if err := mr.RegisterMethod("getblockheaderbyheight", GetBlockHeaderByHeight_Handler{}, GetBlockHeaderByHeight_Params{}, GetBlockHeaderByHeight_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
if err := mr.RegisterMethod("getblock", GetBlock_Handler{}, GetBlock_Params{}, GetBlock_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
if err := mr.RegisterMethod("get_info", GetInfo_Handler{}, GetInfo_Params{}, GetInfo_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
if err := mr.RegisterMethod("gettxpool", GetTxPool_Handler{}, GetTxPool_Params{}, GetTxPool_Result{}); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
http.HandleFunc("/", hello) |
||||
|
http.Handle("/json_rpc", mr) |
||||
|
|
||||
|
// handle nasty http requests
|
||||
|
http.HandleFunc("/getoutputs.bin", getoutputs) // stream any outputs to server, can make wallet work offline
|
||||
|
http.HandleFunc("/gettransactions", gettransactions) |
||||
|
//http.HandleFunc("/json_rpc/debug", mr.ServeDebug)
|
||||
|
|
||||
|
if err := http.ListenAndServe("127.0.0.1:9999", http.DefaultServeMux); err != nil { |
||||
|
log.Fatalln(err) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func hello(w http.ResponseWriter, r *http.Request) { |
||||
|
io.WriteString(w, "Hello world!") |
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
// 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 rpcserver |
||||
|
|
||||
|
// get block template handler not implemented
|
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "context" |
||||
|
|
||||
|
//import "log"
|
||||
|
//import "net/http"
|
||||
|
|
||||
|
import "github.com/intel-go/fastjson" |
||||
|
import "github.com/osamingo/jsonrpc" |
||||
|
|
||||
|
type ( |
||||
|
SubmitBlock_Handler struct{} |
||||
|
SubmitBlock_Params struct { |
||||
|
Wallet_Address string `json:"wallet_address"` |
||||
|
Reserve_size uint64 `json:"reserve_size"` |
||||
|
} |
||||
|
SubmitBlock_Result struct { |
||||
|
Blocktemplate_blob string `json:"blocktemplate_blob"` |
||||
|
Difficulty uint64 `json:"difficulty"` |
||||
|
Height uint64 `json:"height"` |
||||
|
Prev_Hash string `json:"prev_hash"` |
||||
|
Reserved_Offset uint64 `json:"reserved_offset"` |
||||
|
Status string `json:"status"` |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
func (h SubmitBlock_Handler) ServeJSONRPC(c context.Context, params *fastjson.RawMessage) (interface{}, *jsonrpc.Error) { |
||||
|
|
||||
|
var p GetBlockTemplate_Params |
||||
|
if err := jsonrpc.Unmarshal(params, &p); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
// Wallet_Address needs to validated before
|
||||
|
|
||||
|
return SubmitBlock_Result{ |
||||
|
Status: "NOT IMPLEMENTED", |
||||
|
}, nil |
||||
|
} |
@ -1,9 +0,0 @@ |
|||||
package blockchain |
|
||||
|
|
||||
// version 1 transaction support
|
|
||||
const SIGNATURE_V1_LENGTH = 64 |
|
||||
|
|
||||
type Signature_v1 struct { |
|
||||
R [32]byte |
|
||||
C [32]byte |
|
||||
} |
|
@ -0,0 +1,299 @@ |
|||||
|
// 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 "time"
|
||||
|
/*import "bytes" |
||||
|
import "encoding/binary" |
||||
|
|
||||
|
import "github.com/romana/rlog" |
||||
|
|
||||
|
*/ |
||||
|
//import "github.com/romana/rlog"
|
||||
|
|
||||
|
import "runtime/debug" |
||||
|
|
||||
|
import log "github.com/sirupsen/logrus" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/block" |
||||
|
import "github.com/deroproject/derosuite/crypto" |
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
import "github.com/deroproject/derosuite/crypto/ringct" |
||||
|
import "github.com/deroproject/derosuite/transaction" |
||||
|
import "github.com/deroproject/derosuite/emission" |
||||
|
|
||||
|
/* This function verifies tx fully, means all checks, |
||||
|
* if the transaction has passed the check it can be added to mempool, relayed or added to blockchain |
||||
|
* the transaction has already been deserialized thats it |
||||
|
* */ |
||||
|
func (chain *Blockchain) Verify_Transaction(tx *transaction.Transaction) (result bool) { |
||||
|
|
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
/* Coinbase transactions need to verify the amount of coins |
||||
|
* */ |
||||
|
func (chain *Blockchain) Verify_Transaction_Coinbase(cbl *block.Complete_Block, minertx *transaction.Transaction) (result bool) { |
||||
|
|
||||
|
if !minertx.IsCoinbase() { // transaction is not coinbase, return failed
|
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// coinbase transactions only have 1 vin, 1 vout
|
||||
|
if len(minertx.Vin) != 1 { |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
if len(minertx.Vout) != 1 { |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// check whether the height mentioned in tx.Vin is equal to block height
|
||||
|
// this does NOT hold for genesis block so test it differently
|
||||
|
|
||||
|
expected_height := chain.Load_Height_for_BL_ID(cbl.Bl.Prev_Hash) |
||||
|
expected_height++ |
||||
|
if cbl.Bl.GetHash() == globals.Config.Genesis_Block_Hash { |
||||
|
expected_height = 0 |
||||
|
} |
||||
|
if minertx.Vin[0].(transaction.Txin_gen).Height != expected_height { |
||||
|
logger.Warnf(" Rejected Height %d should be %d", minertx.Vin[0].(transaction.Txin_gen).Height, chain.Load_Height_for_BL_ID(cbl.Bl.Prev_Hash)) |
||||
|
return false |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// verify coins amount ( minied amount ) + the fees colllected which is sum of all tx included in this block
|
||||
|
// and whether it has been calculated correctly
|
||||
|
total_fees := uint64(0) |
||||
|
for i := 0; i < len(cbl.Txs); i++ { |
||||
|
total_fees += cbl.Txs[i].RctSignature.Get_TX_Fee() |
||||
|
} |
||||
|
|
||||
|
total_reward := minertx.Vout[0].Amount |
||||
|
base_reward := total_reward - total_fees |
||||
|
|
||||
|
// size of block = size of miner_tx + size of all non coinbase tx
|
||||
|
sizeofblock := uint64(0) |
||||
|
sizeofblock += uint64(len(cbl.Bl.Miner_tx.Serialize())) |
||||
|
// logger.Infof("size of block %d sizeof miner tx %d", sizeofblock, len(cbl.Bl.Miner_tx.Serialize()))
|
||||
|
for i := 0; i < len(cbl.Txs); i++ { |
||||
|
sizeofblock += uint64(len(cbl.Txs[i].Serialize())) |
||||
|
// logger.Infof("size of tx i %d tx size %d total size %d", i, uint64(len(cbl.Txs[i].Serialize())) ,sizeofblock)
|
||||
|
} |
||||
|
|
||||
|
median_block_size := chain.Get_Median_BlockSize_At_Block(cbl.Bl.Prev_Hash) |
||||
|
|
||||
|
already_generated_coins := chain.Load_Already_Generated_Coins_for_BL_ID(cbl.Bl.Prev_Hash) |
||||
|
|
||||
|
base_reward_calculated := emission.GetBlockReward(median_block_size, sizeofblock, already_generated_coins, 6, 0) |
||||
|
if base_reward != base_reward_calculated { |
||||
|
logger.Warnf("Base reward %d should be %d", base_reward, base_reward_calculated) |
||||
|
logger.Warnf("median_block_size %d block_size %d already already_generated_coins %d", median_block_size, sizeofblock, |
||||
|
already_generated_coins) |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
for i := sizeofblock-4000; i < (sizeofblock+4000);i++{ |
||||
|
// now we need to verify whether base reward is okay
|
||||
|
//base_reward_calculated := emission.GetBlockReward(median_block_size,sizeofblock,already_generated_coins,6,0)
|
||||
|
|
||||
|
base_reward_calculated := emission.GetBlockReward(median_block_size,i,already_generated_coins,6,0) |
||||
|
|
||||
|
if base_reward == base_reward_calculated { |
||||
|
logger.Warnf("Base reward %d should be %d size %d", base_reward, base_reward_calculated,i) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
*/ |
||||
|
|
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
// all non miner tx must be non-coinbase tx
|
||||
|
// each check is placed in a separate block of code, to avoid ambigous code or faulty checks
|
||||
|
// all check are placed and not within individual functions ( so as we cannot skip a check )
|
||||
|
func (chain *Blockchain) Verify_Transaction_NonCoinbase(tx *transaction.Transaction) (result bool) { |
||||
|
result = false |
||||
|
|
||||
|
var tx_hash crypto.Hash |
||||
|
defer func() { // safety so if anything wrong happens, verification fails
|
||||
|
if r := recover(); r != nil { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Warnf("Recovered while Verifying transaction, failed verification, Stack trace below") |
||||
|
logger.Warnf("Stack trace \n%s", debug.Stack()) |
||||
|
result = false |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
tx_hash = tx.GetHash() |
||||
|
|
||||
|
if tx.Version != 2 { |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// make sure atleast 1 vin and 1 vout are there
|
||||
|
if len(tx.Vin) < 1 || len(tx.Vout) < 1 { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Warnf("Incoming TX does NOT have atleast 1 vin and 1 vout") |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// this means some other checks have failed somewhere else
|
||||
|
if tx.IsCoinbase() { // transaction coinbase must never come here
|
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Warnf("Coinbase tx in non coinbase path, Please investigate") |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// Vin can be only specific type rest all make the fail case
|
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
switch tx.Vin[i].(type) { |
||||
|
case transaction.Txin_gen: |
||||
|
return false // this is for coinbase so fail it
|
||||
|
case transaction.Txin_to_key: // pass
|
||||
|
default: |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Vout can be only specific type rest all make th fail case
|
||||
|
for i := 0; i < len(tx.Vout); i++ { |
||||
|
switch tx.Vout[i].Target.(type) { |
||||
|
case transaction.Txout_to_key: // pass
|
||||
|
default: |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Vout should have amount 0
|
||||
|
for i := 0; i < len(tx.Vout); i++ { |
||||
|
if tx.Vout[i].Amount != 0 { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash, "Amount": tx.Vout[i].Amount}).Warnf("Amount must be zero in ringCT world") |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// just some extra logs for testing purposes
|
||||
|
if len(tx.Vin) >= 3 { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Warnf("tx has more than 3 inputs") |
||||
|
} |
||||
|
|
||||
|
if len(tx.Vout) >= 3 { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Warnf("tx has more than 3 outputs") |
||||
|
} |
||||
|
|
||||
|
// check the mixin , it should be atleast 4 and should be same through out the tx ( all other inputs)
|
||||
|
// someone did send a mixin of 3 in 12006 block height
|
||||
|
mixin := len(tx.Vin[0].(transaction.Txin_to_key).Key_offsets) |
||||
|
if mixin < 3 { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash, "Mixin": mixin}).Warnf("Mixin must be atleast 3 in ringCT world") |
||||
|
return false |
||||
|
} |
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
if mixin != len(tx.Vin[i].(transaction.Txin_to_key).Key_offsets) { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash, "Mixin": mixin}).Warnf("Mixin must be same for entire TX in ringCT world") |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// duplicate ringmembers are not allowed, check them here
|
||||
|
// just in case protect ourselves as much as we can
|
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
ring_members := map[uint64]bool{} // create a separate map for each input
|
||||
|
ring_member := uint64(0) |
||||
|
for j := 0; j < len(tx.Vin[i].(transaction.Txin_to_key).Key_offsets); j++ { |
||||
|
ring_member += tx.Vin[i].(transaction.Txin_to_key).Key_offsets[j] |
||||
|
if _, ok := ring_members[ring_member]; ok { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash, "input_index": i}).Warnf("Duplicate ring member within the TX") |
||||
|
return false |
||||
|
} |
||||
|
ring_members[ring_member] = true // add member to ring member
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// check whether the key image is duplicate within the inputs
|
||||
|
// NOTE: a block wide key_image duplication is done during block testing but we are still keeping it
|
||||
|
{ |
||||
|
kimages := map[crypto.Hash]bool{} |
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
if _, ok := kimages[tx.Vin[i].(transaction.Txin_to_key).K_image]; ok { |
||||
|
logger.WithFields(log.Fields{ |
||||
|
"txid": tx_hash, |
||||
|
"kimage": tx.Vin[i].(transaction.Txin_to_key).K_image, |
||||
|
}).Warnf("TX using duplicate inputs within the TX") |
||||
|
return false |
||||
|
} |
||||
|
kimages[tx.Vin[i].(transaction.Txin_to_key).K_image] = true // add element to map for next check
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// check whether the key image is low order attack, if yes reject it right now
|
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
k_image := ringct.Key(tx.Vin[i].(transaction.Txin_to_key).K_image) |
||||
|
curve_order := ringct.CurveOrder() |
||||
|
mult_result := ringct.ScalarMultKey(&k_image, &curve_order) |
||||
|
if *mult_result != ringct.Identity { |
||||
|
logger.WithFields(log.Fields{ |
||||
|
"txid": tx_hash, |
||||
|
"kimage": tx.Vin[i].(transaction.Txin_to_key).K_image, |
||||
|
"curve_order": curve_order, |
||||
|
"mult_result": *mult_result, |
||||
|
"identity": ringct.Identity, |
||||
|
}).Warnf("TX contains a low order key image attack, but we are already safeguarded") |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// a similiar block level check is done for double spending attacks within the block itself
|
||||
|
// check whether the key image is already used or spent earlier ( in blockchain )
|
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
k_image := ringct.Key(tx.Vin[i].(transaction.Txin_to_key).K_image) |
||||
|
if chain.Read_KeyImage_Status(crypto.Hash(k_image)) { |
||||
|
logger.WithFields(log.Fields{ |
||||
|
"txid": tx_hash, |
||||
|
"kimage": k_image, |
||||
|
}).Warnf("Key image is already spent, attempt to double spend ") |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// check whether the TX contains a signature or NOT
|
||||
|
switch tx.RctSignature.Get_Sig_Type() { |
||||
|
case ringct.RCTTypeSimple, ringct.RCTTypeFull: // default case, pass through
|
||||
|
default: |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Warnf("TX does NOT contain a ringct signature. It is NOT possible") |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// expand the signature first
|
||||
|
// whether the inputs are mature and can be used at time is verified while expanding the inputs
|
||||
|
if !chain.Expand_Transaction_v2(tx) { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Warnf("TX inputs could not be expanded or inputs are NOT mature") |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// check the ring signature
|
||||
|
if !tx.RctSignature.Verify() { |
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Warnf("TX RCT Signature failed") |
||||
|
return false |
||||
|
|
||||
|
} |
||||
|
|
||||
|
logger.WithFields(log.Fields{"txid": tx_hash}).Debugf("TX successfully verified") |
||||
|
|
||||
|
return true |
||||
|
} |
@ -0,0 +1,96 @@ |
|||||
|
// 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 "math/big" |
||||
|
import "github.com/deroproject/derosuite/config" |
||||
|
|
||||
|
// this file implements the logic to calculate fees dynamicallly
|
||||
|
|
||||
|
// get mininum size of block
|
||||
|
func Get_Block_Minimum_Size(version uint64) uint64 { |
||||
|
return config.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE |
||||
|
} |
||||
|
|
||||
|
// get maximum size of TX
|
||||
|
func Get_Transaction_Maximum_Size() uint64 { |
||||
|
return config.CRYPTONOTE_MAX_TX_SIZE |
||||
|
} |
||||
|
|
||||
|
// get per KB fees which is dependent of block reward and median_block_size
|
||||
|
//
|
||||
|
func (chain *Blockchain) Get_Dynamic_per_kb_fee(block_reward, median_block_size, version uint64) uint64 { |
||||
|
fee_per_kb_base := config.DYNAMIC_FEE_PER_KB_BASE_FEE_V5 |
||||
|
|
||||
|
min_block_size := Get_Block_Minimum_Size(version) |
||||
|
if median_block_size < min_block_size { |
||||
|
median_block_size = min_block_size |
||||
|
} |
||||
|
|
||||
|
var unscaled_fee_per_kb big.Int |
||||
|
|
||||
|
unscaled_fee_per_kb.SetUint64((fee_per_kb_base * min_block_size) / median_block_size) |
||||
|
unscaled_fee_per_kb.Mul(&unscaled_fee_per_kb, big.NewInt(int64(block_reward))) // block reward is always positive
|
||||
|
unscaled_fee_per_kb.Div(&unscaled_fee_per_kb, big.NewInt(int64(config.DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD))) |
||||
|
|
||||
|
if !unscaled_fee_per_kb.IsUint64() { |
||||
|
panic("Get_Dynamic_per_kb_fee has issues, Need to fix it urgently\n") |
||||
|
} |
||||
|
|
||||
|
lo := unscaled_fee_per_kb.Uint64() |
||||
|
// we need to quantise it 8 decimal // make 4 lower digits 0
|
||||
|
mask := uint64(10000) |
||||
|
|
||||
|
qlo := (lo + mask - 1) / mask * mask |
||||
|
|
||||
|
//logger.Infof("dynamic fee lo= %d qlo=%d", lo, qlo)
|
||||
|
|
||||
|
return qlo |
||||
|
} |
||||
|
|
||||
|
// this will give the dynamic fee at any specfic height
|
||||
|
func (chain *Blockchain) Get_Dynamic_Fee_Rate(height uint64) uint64 { |
||||
|
var base_reward, median_block_size uint64 |
||||
|
|
||||
|
// sanitize height
|
||||
|
if height >= chain.Get_Height() { |
||||
|
height = chain.Load_Height_for_BL_ID(chain.Get_Top_ID()) |
||||
|
} |
||||
|
|
||||
|
block_id_at_height, _ := chain.Load_BL_ID_at_Height(height) |
||||
|
|
||||
|
median_block_size = chain.Get_Median_BlockSize_At_Block(block_id_at_height) |
||||
|
base_reward = chain.Load_Block_Reward(block_id_at_height) |
||||
|
|
||||
|
return chain.Get_Dynamic_per_kb_fee(base_reward, median_block_size, 0) |
||||
|
} |
||||
|
|
||||
|
// get the tx fee
|
||||
|
// this function assumes that dynamic fees has been calculated as per requirement
|
||||
|
// for every part of 1KB multiply by dynamic_fee_per_kb
|
||||
|
// the dynamic fee should be calculated on the basis of the current top
|
||||
|
func (chain *Blockchain) Calculate_TX_fee(dynamic_fee_per_kb uint64, tx_size uint64) uint64 { |
||||
|
size_in_kb := tx_size / 1024 |
||||
|
|
||||
|
if (tx_size % 1024) != 0 { // for any part there of, use a full KB fee
|
||||
|
size_in_kb += 1 |
||||
|
} |
||||
|
|
||||
|
needed_fee := size_in_kb * dynamic_fee_per_kb |
||||
|
return needed_fee |
||||
|
|
||||
|
} |
@ -0,0 +1,78 @@ |
|||||
|
#!/usr/bin/env bash |
||||
|
|
||||
|
package=$1 |
||||
|
package_split=(${package//\// }) |
||||
|
package_name=${package_split[-1]} |
||||
|
|
||||
|
|
||||
|
CURDIR=`/bin/pwd` |
||||
|
BASEDIR=$(dirname $0) |
||||
|
ABSPATH=$(readlink -f $0) |
||||
|
ABSDIR=$(dirname $ABSPATH) |
||||
|
|
||||
|
|
||||
|
PLATFORMS="darwin/amd64" # amd64 only as of go1.5 |
||||
|
PLATFORMS="$PLATFORMS windows/amd64 windows/386" # arm compilation not available for Windows |
||||
|
PLATFORMS="$PLATFORMS linux/amd64 linux/386" |
||||
|
#PLATFORMS="$PLATFORMS linux/ppc64le" is it common enough ?? |
||||
|
#PLATFORMS="$PLATFORMS linux/mips64le" # experimental in go1.6 is it common enough ?? |
||||
|
PLATFORMS="$PLATFORMS freebsd/amd64 freebsd/386" |
||||
|
PLATFORMS="$PLATFORMS netbsd/amd64" # amd64 only as of go1.6 |
||||
|
PLATFORMS="$PLATFORMS openbsd/amd64" # amd64 only as of go1.6 |
||||
|
PLATFORMS="$PLATFORMS dragonfly/amd64" # amd64 only as of go1.5 |
||||
|
#PLATFORMS="$PLATFORMS plan9/amd64 plan9/386" # as of go1.4, is it common enough ?? |
||||
|
PLATFORMS="$PLATFORMS solaris/amd64" # as of go1.3 |
||||
|
|
||||
|
|
||||
|
PLATFORMS_ARM="linux freebsd netbsd" |
||||
|
|
||||
|
type setopt >/dev/null 2>&1 |
||||
|
|
||||
|
SCRIPT_NAME=`basename "$0"` |
||||
|
FAILURES="" |
||||
|
CURRENT_DIRECTORY=${PWD##*/} |
||||
|
OUTPUT="$package_name" # if no src file given, use current dir name |
||||
|
|
||||
|
|
||||
|
for PLATFORM in $PLATFORMS; do |
||||
|
GOOS=${PLATFORM%/*} |
||||
|
GOARCH=${PLATFORM#*/} |
||||
|
OUTPUT_DIR="${ABSDIR}/build/dero_${GOOS}_${GOARCH}" |
||||
|
BIN_FILENAME="${OUTPUT}-${GOOS}-${GOARCH}" |
||||
|
echo mkdir -p $OUTPUT_DIR |
||||
|
if [[ "${GOOS}" == "windows" ]]; then BIN_FILENAME="${BIN_FILENAME}.exe"; fi |
||||
|
CMD="GOOS=${GOOS} GOARCH=${GOARCH} go build -o $OUTPUT_DIR/${BIN_FILENAME} $package" |
||||
|
echo "${CMD}" |
||||
|
eval $CMD || FAILURES="${FAILURES} ${PLATFORM}" |
||||
|
done |
||||
|
|
||||
|
# ARM64 builds only for linux |
||||
|
if [[ $PLATFORMS_ARM == *"linux"* ]]; then |
||||
|
GOOS="linux" |
||||
|
GOARCH="arm64" |
||||
|
OUTPUT_DIR="${ABSDIR}/build/dero_${GOOS}_${GOARCH}" |
||||
|
CMD="GOOS=linux GOARCH=arm64 go build -o $OUTPUT_DIR/${OUTPUT}-linux-arm64 $package" |
||||
|
echo "${CMD}" |
||||
|
eval $CMD || FAILURES="${FAILURES} ${PLATFORM}" |
||||
|
fi |
||||
|
|
||||
|
|
||||
|
|
||||
|
for GOOS in $PLATFORMS_ARM; do |
||||
|
GOARCH="arm" |
||||
|
# build for each ARM version |
||||
|
for GOARM in 7 6 5; do |
||||
|
OUTPUT_DIR="${ABSDIR}/build/dero_${GOOS}_${GOARCH}${GOARM}" |
||||
|
BIN_FILENAME="${OUTPUT}-${GOOS}-${GOARCH}${GOARM}" |
||||
|
CMD="GOARM=${GOARM} GOOS=${GOOS} GOARCH=${GOARCH} go build -o $OUTPUT_DIR/${BIN_FILENAME} $package" |
||||
|
echo "${CMD}" |
||||
|
eval "${CMD}" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}" |
||||
|
done |
||||
|
done |
||||
|
|
||||
|
# eval errors |
||||
|
if [[ "${FAILURES}" != "" ]]; then |
||||
|
echo "" |
||||
|
echo "${SCRIPT_NAME} failed on: ${FAILURES}" |
||||
|
exit 1 |
||||
|
fi |
@ -0,0 +1,106 @@ |
|||||
|
// 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 checkpoints |
||||
|
|
||||
|
// generate main net checkpoints automatically from file mainnet_checkpoints.dat
|
||||
|
|
||||
|
//go:generate sh -c "echo // Code generated by go generate DO NOT EDIT. > mainnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo // This file contains all the mainnet checkpoints > mainnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo // please read checkpoints.go comments > mainnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo package checkpoints >> mainnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo >> mainnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo var mainnet_checkpoints = []byte{ >> mainnet_checkpoints.go"
|
||||
|
//go:generate sh -c "xxd -i < mainnet_checkpoints.dat >> mainnet_checkpoints.go"
|
||||
|
//go:generate sh -c "truncate -s-1 mainnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo ,} >> mainnet_checkpoints.go"
|
||||
|
|
||||
|
//go:generate sh -c "echo // Code generated by go generate DO NOT EDIT. > testnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo // This file contains all the testnet checkpoints > testnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo // please read checkpoints.go comments > testnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo package checkpoints >> testnet_checkpoints.go"
|
||||
|
//go:generate sh -c "echo >> testnet_checkpoints.go"
|
||||
|
|
||||
|
// generate blank file if no checkpoints
|
||||
|
//go:generate sh -c "if [ ! -s testnet_checkpoints.dat ]; then echo var testnet_checkpoints = []byte{} >> testnet_checkpoints.go; fi;"
|
||||
|
|
||||
|
//go:generate sh -c " if [ -s testnet_checkpoints.dat ]; then echo var testnet_checkpoints = []byte{ >> testnet_checkpoints.go; fi"
|
||||
|
//go:generate sh -c "if [ -s testnet_checkpoints.dat ]; then xxd -i < testnet_checkpoints.dat >> testnet_checkpoints.go;fi"
|
||||
|
//go:generate sh -c "if [ -s testnet_checkpoints.dat ]; then truncate -s-1 testnet_checkpoints.go; fi"
|
||||
|
//go:generate sh -c "if [ -s testnet_checkpoints.dat ]; then echo ,} >> testnet_checkpoints.go;fi "
|
||||
|
|
||||
|
import "fmt" |
||||
|
|
||||
|
import "github.com/romana/rlog" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/crypto" |
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
|
||||
|
// this file handles and maintains checkpoints which are used by blockchain to skip some checks on known parts of the chain
|
||||
|
// the skipping of the checks can be disabled by command line arguments
|
||||
|
|
||||
|
var mainnet_checkpoints_height uint64 = uint64(len(mainnet_checkpoints) / 32) // each checkpoint is 32 bytes in size
|
||||
|
var testnet_checkpoints_height uint64 = uint64(len(testnet_checkpoints) / 32) // each checkpoint is 32 bytes in size
|
||||
|
|
||||
|
func init() { |
||||
|
rlog.Tracef(1, "Loaded %d checkpoints for mainnet hardcoded", mainnet_checkpoints_height) |
||||
|
rlog.Tracef(1, "Loaded %d checkpoints for testnet hardcoded", testnet_checkpoints_height) |
||||
|
} |
||||
|
|
||||
|
// gives length of currently available checkpoints
|
||||
|
func Length() uint64 { |
||||
|
switch globals.Config.Name { |
||||
|
case "mainnet": |
||||
|
return mainnet_checkpoints_height |
||||
|
case "testnet": |
||||
|
return testnet_checkpoints_height |
||||
|
default: |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
// we can never reach here
|
||||
|
//return 0
|
||||
|
} |
||||
|
|
||||
|
// tell whether a checkpoint is known in the current selected network
|
||||
|
func IsCheckPointKnown(hash crypto.Hash, height uint64) (result bool) { |
||||
|
|
||||
|
var known_hash crypto.Hash |
||||
|
|
||||
|
switch globals.Config.Name { |
||||
|
case "mainnet": |
||||
|
if height < mainnet_checkpoints_height { |
||||
|
copy(known_hash[:], mainnet_checkpoints[32*height:]) |
||||
|
if known_hash == hash { |
||||
|
result = true |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
case "testnet": |
||||
|
if height < testnet_checkpoints_height { |
||||
|
copy(known_hash[:], testnet_checkpoints[32*height:]) |
||||
|
if known_hash == hash { |
||||
|
result = true |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
default: |
||||
|
panic(fmt.Sprintf("Unknown Network \"%s\"", globals.Config.Name)) |
||||
|
} |
||||
|
return |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
// 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
|
||||
|
|
||||
|
package checkpoints |
||||
|
|
||||
|
import "testing" |
||||
|
|
||||
|
// Needs to expand test to cover failure conditions
|
||||
|
func Test_Part1(t *testing.T) { |
||||
|
|
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
// please read checkpoints.go comments
|
||||
|
package checkpoints |
||||
|
|
||||
|
var testnet_checkpoints = []byte{} |
@ -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,167 @@ |
|||||
|
// 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 main |
||||
|
|
||||
|
/* this file handles communication with the daemon |
||||
|
* this includes receiving output information |
||||
|
* * |
||||
|
*/ |
||||
|
import "io" |
||||
|
import "fmt" |
||||
|
import "net" |
||||
|
import "time" |
||||
|
import "sync" |
||||
|
import "net/http" |
||||
|
import "compress/gzip" |
||||
|
|
||||
|
//import "github.com/romana/rlog"
|
||||
|
//import "github.com/pierrec/lz4"
|
||||
|
import "github.com/ybbus/jsonrpc" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
import "github.com/deroproject/derosuite/blockchain/rpcserver" |
||||
|
|
||||
|
var Wallet_Height uint64 // height of wallet
|
||||
|
var Daemon_Height uint64 // height of daemon
|
||||
|
var Connected bool = true |
||||
|
|
||||
|
var rpcClient *jsonrpc.RPCClient |
||||
|
var netClient *http.Client |
||||
|
var endpoint string |
||||
|
|
||||
|
var output_lock sync.Mutex |
||||
|
|
||||
|
// this is as simple as it gets
|
||||
|
// single threaded communication to get the daemon status and height
|
||||
|
func Run_Communication_Engine() { |
||||
|
|
||||
|
// check if user specified daemon address explicitly
|
||||
|
if globals.Arguments["--daemon-address"] != nil { |
||||
|
daemon_address := globals.Arguments["--daemon-address"].(string) |
||||
|
|
||||
|
remote_end, err := net.ResolveTCPAddr("tcp", daemon_address) |
||||
|
if err != nil { |
||||
|
globals.Logger.Warnf("Daemon address \"%s\" is invalid. parse err %s", daemon_address, err) |
||||
|
} else { |
||||
|
|
||||
|
fmt.Printf("%+v\n", remote_end.IP) |
||||
|
if remote_end.IP == nil || remote_end.IP.IsUnspecified() { // user never provided an ipaddress, use loopback
|
||||
|
globals.Logger.Debugf("Setting loopback ip on daemon endpoint") |
||||
|
remote_end.IP = net.IPv4(127, 0, 0, 1) |
||||
|
} |
||||
|
endpoint = remote_end.String() |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// if user provided endpoint has error, use default
|
||||
|
if endpoint == "" { |
||||
|
endpoint = "127.0.0.1:9999" |
||||
|
if !globals.IsMainnet() { |
||||
|
endpoint = "127.0.0.1:28091" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
globals.Logger.Debugf("Daemon endpoint %s", endpoint) |
||||
|
|
||||
|
// TODO enable socks support here
|
||||
|
var netTransport = &http.Transport{ |
||||
|
Dial: (&net.Dialer{ |
||||
|
Timeout: 5 * time.Second, // 5 second timeout
|
||||
|
}).Dial, |
||||
|
TLSHandshakeTimeout: 5 * time.Second, |
||||
|
} |
||||
|
|
||||
|
netClient = &http.Client{ |
||||
|
Timeout: time.Second * 10, |
||||
|
Transport: netTransport, |
||||
|
} |
||||
|
|
||||
|
// create client
|
||||
|
rpcClient = jsonrpc.NewRPCClient("http://" + endpoint + "/json_rpc") |
||||
|
|
||||
|
for { |
||||
|
time.Sleep(1 * time.Second) // ping server every second
|
||||
|
// execute rpc to service
|
||||
|
response, err := rpcClient.Call("get_info") |
||||
|
|
||||
|
// notify user of any state change
|
||||
|
// if daemon connection breaks or comes live again
|
||||
|
if err == nil { |
||||
|
if !Connected { |
||||
|
globals.Logger.Infof("Connection to RPC server successful") |
||||
|
Connected = true |
||||
|
} |
||||
|
} else { |
||||
|
if Connected { |
||||
|
globals.Logger.Warnf("Connection to RPC server Failed err %s", err) |
||||
|
Connected = false |
||||
|
} |
||||
|
continue // try next time
|
||||
|
} |
||||
|
var info rpcserver.GetInfo_Result |
||||
|
err = response.GetObject(&info) |
||||
|
if err != nil { |
||||
|
globals.Logger.Warnf("Daemon getinfo RPC parsing error err: %s\n", err) |
||||
|
continue |
||||
|
} |
||||
|
// detect whether both are in different modes
|
||||
|
// daemon is in testnet and wallet in mainnet or
|
||||
|
// daemon
|
||||
|
if info.Testnet != !globals.IsMainnet() { |
||||
|
globals.Logger.Warnf("Mainnet/TestNet is different between wallet/daemon.Please run daemon/wallet without --testnet") |
||||
|
} |
||||
|
Daemon_Height = info.Height |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// get the outputs from the daemon, requesting specfic outputs
|
||||
|
// the range can be anything
|
||||
|
// if stop is zero,
|
||||
|
// the daemon will flush out everything it has ASAP
|
||||
|
// the stream can be saved and used later on
|
||||
|
func Get_Outputs(start uint64, stop uint64) { |
||||
|
|
||||
|
output_lock.Lock() |
||||
|
defer output_lock.Unlock() |
||||
|
if Connected { // only execute query if we are connected
|
||||
|
|
||||
|
response, err := http.Get(fmt.Sprintf("http://%s/getoutputs.bin?start=%d", endpoint, start)) |
||||
|
if err != nil { |
||||
|
globals.Logger.Warnf("Error while requesting outputs from daemon err %s", err) |
||||
|
// os.Exit(1)
|
||||
|
} else { |
||||
|
defer response.Body.Close() |
||||
|
|
||||
|
// lz4reader := lz4.NewReader(response.Body)
|
||||
|
// io.Copy(pipe_writer, lz4reader)
|
||||
|
|
||||
|
gzipreader, err := gzip.NewReader(response.Body) |
||||
|
if err != nil { |
||||
|
globals.Logger.Warnf("Error while decompressing output from daemon err: %s ", err) |
||||
|
return |
||||
|
} |
||||
|
defer gzipreader.Close() |
||||
|
io.Copy(pipe_writer, gzipreader) |
||||
|
|
||||
|
} |
||||
|
// contents, err := ioutil.ReadAll(response.Body)
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
// 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
|
||||
|
|
||||
|
package main |
||||
|
|
||||
|
import "testing" |
||||
|
|
||||
|
// Needs to expand test to cover failure conditions
|
||||
|
func Test_Part1(t *testing.T) { |
||||
|
|
||||
|
} |
@ -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 main |
||||
|
|
||||
|
import "io" |
||||
|
import "fmt" |
||||
|
import "strings" |
||||
|
|
||||
|
import "github.com/chzyer/readline" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
import "github.com/deroproject/derosuite/walletapi" |
||||
|
|
||||
|
// handle menu if a wallet is currently opened
|
||||
|
func display_easymenu_post_open_command(l *readline.Instance) { |
||||
|
w := l.Stderr() |
||||
|
io.WriteString(w, "Menu:\n") |
||||
|
|
||||
|
io.WriteString(w, "\t\033[1m1\033[0m\tDisplay account Address \n") |
||||
|
if !account.ViewOnly { // hide some commands, if view only wallet
|
||||
|
io.WriteString(w, "\t\033[1m2\033[0m\tDisplay Seed "+color_red+"(Please save seed otherwise your wallet is LOST)\n\033[0m") |
||||
|
} |
||||
|
io.WriteString(w, "\t\033[1m3\033[0m\tDisplay Keys (hex)\n") |
||||
|
io.WriteString(w, "\t\033[1m4\033[0m\tDisplay Watch-able View only wallet key ( cannot spend any funds from this wallet) (hex)\n") |
||||
|
|
||||
|
if !account.ViewOnly { // hide some commands, if view only wallet
|
||||
|
io.WriteString(w, "\t\033[1m5\033[0m\tTransfer ( send DERO) To Another Wallet\n") |
||||
|
io.WriteString(w, "\t\033[1m6\033[0m\tTransfer ( send DERO) To Exchange (payment id mandatory\n") |
||||
|
io.WriteString(w, "\t\033[1m7\033[0m\tCreate Transaction in offline mode\n") |
||||
|
} |
||||
|
|
||||
|
io.WriteString(w, "\t\033[1m8\033[0m\tClose Wallet\n") |
||||
|
|
||||
|
io.WriteString(w, "\n\t\033[1m9\033[0m\tExit menu and start prompt\n") |
||||
|
io.WriteString(w, "\t\033[1m0\033[0m\tExit Wallet\n") |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// this handles all the commands if wallet in menu mode and a wallet is opened
|
||||
|
func handle_easymenu_post_open_command(l *readline.Instance, line string) { |
||||
|
|
||||
|
var err error |
||||
|
_ = err |
||||
|
line = strings.TrimSpace(line) |
||||
|
line_parts := strings.Fields(line) |
||||
|
|
||||
|
if len(line_parts) < 1 { // if no command return
|
||||
|
return |
||||
|
} |
||||
|
|
||||
|
command := "" |
||||
|
if len(line_parts) >= 1 { |
||||
|
command = strings.ToLower(line_parts[0]) |
||||
|
} |
||||
|
|
||||
|
switch command { |
||||
|
case "1": |
||||
|
if account_valid { |
||||
|
fmt.Fprintf(l.Stderr(), "%s\n", account.GetAddress()) |
||||
|
} |
||||
|
case "2": // give user his seed
|
||||
|
if !account.ViewOnly { |
||||
|
display_seed(l) |
||||
|
} |
||||
|
|
||||
|
case "3": // give user his keys in hex form
|
||||
|
display_spend_key(l) |
||||
|
display_view_key(l) |
||||
|
|
||||
|
case "4": // display user keys to create view only wallet
|
||||
|
display_viewwallet_key(l) |
||||
|
case "5", "6", "7": |
||||
|
if !account.ViewOnly { |
||||
|
globals.Logger.Warnf("This command is NOT yet implemented") |
||||
|
} |
||||
|
|
||||
|
case "8": // close and discard user key
|
||||
|
account_valid = false |
||||
|
account = &walletapi.Account{} // overwrite previous instance
|
||||
|
address = "" // empty the address
|
||||
|
Wallet_Height = 0 |
||||
|
|
||||
|
case "9": // enable prompt mode
|
||||
|
menu_mode = false |
||||
|
globals.Logger.Infof("Prompt mode enabled") |
||||
|
case "0", "bye", "exit", "quit": |
||||
|
globals.Exit_In_Progress = true |
||||
|
|
||||
|
default: // just loop
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,132 @@ |
|||||
|
// 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 main |
||||
|
|
||||
|
import "io" |
||||
|
import "strings" |
||||
|
|
||||
|
import "github.com/chzyer/readline" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
import "github.com/deroproject/derosuite/walletapi" |
||||
|
|
||||
|
// display menu before a wallet is opened
|
||||
|
func display_easymenu_pre_open_command(l *readline.Instance) { |
||||
|
w := l.Stderr() |
||||
|
io.WriteString(w, "Menu:\n") |
||||
|
io.WriteString(w, "\t\033[1m1\033[0m\tCreate New Wallet\n") |
||||
|
io.WriteString(w, "\t\033[1m2\033[0m\tRecover Wallet using recovery seed (25 words)\n") |
||||
|
io.WriteString(w, "\t\033[1m3\033[0m\tRecover Wallet using recovery key (64 char private spend key hex)\n") |
||||
|
io.WriteString(w, "\t\033[1m4\033[0m\tCreate Watch-able Wallet (view only) using wallet view key\n") |
||||
|
|
||||
|
io.WriteString(w, "\n\t\033[1m9\033[0m\tExit menu and start prompt\n") |
||||
|
io.WriteString(w, "\t\033[1m0\033[0m\tExit Wallet\n") |
||||
|
} |
||||
|
|
||||
|
// handle all commands
|
||||
|
func handle_easymenu_pre_open_command(l *readline.Instance, line string) { |
||||
|
var err error |
||||
|
line = strings.TrimSpace(line) |
||||
|
line_parts := strings.Fields(line) |
||||
|
|
||||
|
if len(line_parts) < 1 { // if no command return
|
||||
|
return |
||||
|
} |
||||
|
|
||||
|
command := "" |
||||
|
if len(line_parts) >= 1 { |
||||
|
command = strings.ToLower(line_parts[0]) |
||||
|
} |
||||
|
|
||||
|
account_state := account_valid |
||||
|
switch command { |
||||
|
case "1": // create a new random account
|
||||
|
if account_valid { |
||||
|
globals.Logger.Warnf("Account already exists. Cannot create new account") |
||||
|
break |
||||
|
} |
||||
|
account = Create_New_Account(l) |
||||
|
account_valid = true |
||||
|
globals.Logger.Debugf("Seed Language %s", account.SeedLanguage) |
||||
|
address = account.GetAddress().String() |
||||
|
display_seed(l) |
||||
|
|
||||
|
if offline_mode { |
||||
|
go trigger_offline_data_scan() |
||||
|
} |
||||
|
|
||||
|
case "2": // create wallet from recovery seed
|
||||
|
if account_valid { |
||||
|
globals.Logger.Warnf("Account already exists. Cannot recover account") |
||||
|
break |
||||
|
} |
||||
|
seed := read_line_with_prompt(l, "Enter your seed (25 words) : ") |
||||
|
|
||||
|
account, err = walletapi.Generate_Account_From_Recovery_Words(seed) |
||||
|
if err != nil { |
||||
|
globals.Logger.Warnf("Error while recovering seed err %s\n", err) |
||||
|
break |
||||
|
} |
||||
|
account_valid = true |
||||
|
globals.Logger.Debugf("Seed Language %s", account.SeedLanguage) |
||||
|
globals.Logger.Infof("Successfully recovered wallet from seed") |
||||
|
address = account.GetAddress().String() |
||||
|
if offline_mode { |
||||
|
go trigger_offline_data_scan() |
||||
|
} |
||||
|
case "3": // create wallet from hex seed
|
||||
|
account = Create_New_Account_from_seed(l) |
||||
|
if account_valid { |
||||
|
globals.Logger.Infof("Successfully recovered wallet from hex seed") |
||||
|
display_seed(l) |
||||
|
address = account.GetAddress().String() |
||||
|
if offline_mode { |
||||
|
go trigger_offline_data_scan() |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
case "4": // create new view only wallet // TODO user providing wrong key is not being validated, do it ASAP
|
||||
|
account = Create_New_Account_from_viewable_key(l) |
||||
|
if account_valid { |
||||
|
globals.Logger.Infof("Successfully created view only wallet from viewable keys") |
||||
|
address = account.GetAddress().String() |
||||
|
account_valid = true |
||||
|
|
||||
|
if offline_mode { |
||||
|
go trigger_offline_data_scan() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
case "9": |
||||
|
menu_mode = false |
||||
|
globals.Logger.Infof("Prompt mode enabled") |
||||
|
case "0", "bye", "exit", "quit": |
||||
|
globals.Exit_In_Progress = true |
||||
|
default: // just loop
|
||||
|
|
||||
|
} |
||||
|
_ = account_state |
||||
|
|
||||
|
// NOTE: if we are in online mode, it is handled automatically
|
||||
|
// user opened or created a new account
|
||||
|
// rescan blockchain in offline mode
|
||||
|
//if account_state == false && account_valid && offline_mode {
|
||||
|
// go trigger_offline_data_scan()
|
||||
|
//}
|
||||
|
|
||||
|
} |
@ -0,0 +1,502 @@ |
|||||
|
// 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 main |
||||
|
|
||||
|
/// this file implements the wallet and rpc wallet
|
||||
|
|
||||
|
import "io" |
||||
|
import "os" |
||||
|
import "fmt" |
||||
|
import "time" |
||||
|
import "sync" |
||||
|
import "strings" |
||||
|
import "strconv" |
||||
|
import "runtime" |
||||
|
|
||||
|
//import "io/ioutil"
|
||||
|
//import "bufio"
|
||||
|
//import "bytes"
|
||||
|
//import "net/http"
|
||||
|
import "encoding/hex" |
||||
|
|
||||
|
import "github.com/romana/rlog" |
||||
|
import "github.com/chzyer/readline" |
||||
|
import "github.com/docopt/docopt-go" |
||||
|
import log "github.com/sirupsen/logrus" |
||||
|
import "github.com/vmihailenco/msgpack" |
||||
|
|
||||
|
//import "github.com/deroproject/derosuite/address"
|
||||
|
import "github.com/deroproject/derosuite/walletapi" |
||||
|
import "github.com/deroproject/derosuite/crypto" |
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
import "github.com/deroproject/derosuite/walletapi/mnemonics" |
||||
|
|
||||
|
var command_line string = `dero-wallet-cli |
||||
|
DERO : A secure, private blockchain with smart-contracts |
||||
|
|
||||
|
Usage: |
||||
|
derod [--help] [--version] [--offline] [--offline_datafile=<file>] [--testnet] [--prompt] [--debug] [--daemon-address=<host:port>] [--restore-deterministic-wallet] [--electrum-seed=<recovery-seed>] [--socks-proxy=<socks_ip:port>] |
||||
|
derod -h | --help |
||||
|
derod --version |
||||
|
|
||||
|
Options: |
||||
|
-h --help Show this screen. |
||||
|
--version Show version. |
||||
|
--offline Run the wallet in completely offline mode |
||||
|
--offline_datafile=<file> Use the data in offline mode default ("getoutputs.bin") in current dir |
||||
|
--prompt Disable menu and display prompt |
||||
|
--testnet Run in testnet mode. |
||||
|
--debug Debug mode enabled, print log messages |
||||
|
--restore-deterministic-wallet Restore wallet from previously saved recovery seed |
||||
|
--electrum-seed=<recovery-seed> Seed to use while restoring wallet |
||||
|
--password Password to unlock the wallet |
||||
|
--socks-proxy=<socks_ip:port> Use a proxy to connect to Daemon. |
||||
|
--daemon-address=<host:port> Use daemon instance at <host>:<port> |
||||
|
|
||||
|
` |
||||
|
var menu_mode bool = true // default display menu mode
|
||||
|
var account_valid bool = false // if an account has been opened, do not allow to create new account in this session
|
||||
|
var offline_mode bool // whether we are in offline mode
|
||||
|
var sync_in_progress int // whether sync is in progress with daemon
|
||||
|
var account *walletapi.Account = &walletapi.Account{} // all account data is available here
|
||||
|
var address string |
||||
|
var sync_time time.Time // used to suitable update prompt
|
||||
|
|
||||
|
var default_offline_datafile string = "getoutputs.bin" |
||||
|
|
||||
|
// these pipes are used to feed in transaction data to recover valid amounts
|
||||
|
var pipe_reader *io.PipeReader // any output will be read from this end point
|
||||
|
var pipe_writer *io.PipeWriter // any data from daemon or file needs to written here
|
||||
|
|
||||
|
var color_black = "\033[30m" |
||||
|
var color_red = "\033[31m" |
||||
|
var color_green = "\033[32m" |
||||
|
var color_yellow = "\033[33m" |
||||
|
var color_blue = "\033[34m" |
||||
|
var color_magenta = "\033[35m" |
||||
|
var color_cyan = "\033[36m" |
||||
|
var color_white = "\033[37m" |
||||
|
|
||||
|
var prompt_mutex sync.Mutex // prompt lock
|
||||
|
var prompt string = "\033[92mDERO Wallet:\033[32m>>>\033[0m " |
||||
|
|
||||
|
func main() { |
||||
|
|
||||
|
var err error |
||||
|
globals.Arguments, err = docopt.Parse(command_line, nil, true, "DERO daemon : work in progress", false) |
||||
|
if err != nil { |
||||
|
log.Fatalf("Error while parsing options err: %s\n", err) |
||||
|
} |
||||
|
|
||||
|
// We need to initialize readline first, so it changes stderr to ansi processor on windows
|
||||
|
l, err := readline.NewEx(&readline.Config{ |
||||
|
//Prompt: "\033[92mDERO:\033[32m»\033[0m",
|
||||
|
Prompt: prompt, |
||||
|
HistoryFile: "", // wallet never saves any history file anywhere, to prevent any leakage
|
||||
|
AutoComplete: completer, |
||||
|
InterruptPrompt: "^C", |
||||
|
EOFPrompt: "exit", |
||||
|
|
||||
|
HistorySearchFold: true, |
||||
|
FuncFilterInputRune: filterInput, |
||||
|
}) |
||||
|
if err != nil { |
||||
|
panic(err) |
||||
|
} |
||||
|
defer l.Close() |
||||
|
|
||||
|
// parse arguments and setup testnet mainnet
|
||||
|
globals.Initialize() // setup network and proxy
|
||||
|
globals.Logger.Infof("") // a dummy write is required to fully activate logrus
|
||||
|
|
||||
|
// all screen output must go through the readline
|
||||
|
globals.Logger.Out = l.Stdout() |
||||
|
|
||||
|
globals.Logger.Debugf("Arguments %+v", globals.Arguments) |
||||
|
globals.Logger.Infof("DERO Wallet : This version is under heavy development, use it for testing/evaluations purpose only") |
||||
|
globals.Logger.Infof("Copyright 2017-2018 DERO Project. All rights reserved.") |
||||
|
globals.Logger.Infof("OS:%s ARCH:%s GOMAXPROCS:%d", runtime.GOOS, runtime.GOARCH, runtime.GOMAXPROCS(0)) |
||||
|
globals.Logger.Infof("Wallet in %s mode", globals.Config.Name) |
||||
|
|
||||
|
// disable menu mode if requested
|
||||
|
if globals.Arguments["--prompt"].(bool) { |
||||
|
menu_mode = false |
||||
|
} |
||||
|
// lets handle the arguments one by one
|
||||
|
if globals.Arguments["--restore-deterministic-wallet"].(bool) { |
||||
|
// user wants to recover wallet, check whether seed is provided on command line, if not prompt now
|
||||
|
seed := "" |
||||
|
|
||||
|
if globals.Arguments["--electrum-seed"] != nil { |
||||
|
seed = globals.Arguments["--electrum-seed"].(string) |
||||
|
} else { // prompt user for seed
|
||||
|
seed = read_line_with_prompt(l, "Enter your seed (25 words) : ") |
||||
|
} |
||||
|
|
||||
|
account, err = walletapi.Generate_Account_From_Recovery_Words(seed) |
||||
|
if err != nil { |
||||
|
globals.Logger.Warnf("Error while recovering seed err %s\n", err) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
account_valid = true |
||||
|
globals.Logger.Debugf("Seed Language %s", account.SeedLanguage) |
||||
|
globals.Logger.Infof("Successfully recovered wallet from seed") |
||||
|
address = account.GetAddress().String() |
||||
|
} |
||||
|
|
||||
|
// check if offline mode requested
|
||||
|
if globals.Arguments["--offline"].(bool) == true { |
||||
|
offline_mode = true |
||||
|
} else { // we are not in offline mode, start communications with the daemon
|
||||
|
go Run_Communication_Engine() |
||||
|
} |
||||
|
|
||||
|
pipe_reader, pipe_writer = io.Pipe() // create pipes
|
||||
|
|
||||
|
setPasswordCfg := l.GenPasswordConfig() |
||||
|
setPasswordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) { |
||||
|
l.SetPrompt(fmt.Sprintf("Enter password(%v): ", len(line))) |
||||
|
l.Refresh() |
||||
|
return nil, 0, false |
||||
|
}) |
||||
|
l.Refresh() // refresh the prompt
|
||||
|
|
||||
|
// reader ready to parse any data from the file
|
||||
|
go blockchain_data_consumer() |
||||
|
|
||||
|
// update prompt when required
|
||||
|
go update_prompt(l) |
||||
|
|
||||
|
// if wallet has been opened in offline mode by commands supplied at command prompt
|
||||
|
// trigger the offline scan
|
||||
|
if account_valid { |
||||
|
go trigger_offline_data_scan() |
||||
|
} |
||||
|
|
||||
|
// start infinite loop processing user commands
|
||||
|
for { |
||||
|
|
||||
|
if globals.Exit_In_Progress { // exit if requested so
|
||||
|
break |
||||
|
} |
||||
|
if menu_mode { // display menu if requested
|
||||
|
if account_valid { // account is opened, display post menu
|
||||
|
display_easymenu_post_open_command(l) |
||||
|
} else { // account has not been opened display pre open menu
|
||||
|
display_easymenu_pre_open_command(l) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
line, err := l.Readline() |
||||
|
if err == readline.ErrInterrupt { |
||||
|
if len(line) == 0 { |
||||
|
globals.Logger.Infof("Ctrl-C received, Exit in progress\n") |
||||
|
globals.Exit_In_Progress = true |
||||
|
break |
||||
|
} else { |
||||
|
continue |
||||
|
} |
||||
|
} else if err == io.EOF { |
||||
|
break |
||||
|
} |
||||
|
|
||||
|
// pass command to suitable handler
|
||||
|
if menu_mode { |
||||
|
if account_valid { |
||||
|
handle_easymenu_post_open_command(l, line) |
||||
|
} else { |
||||
|
handle_easymenu_pre_open_command(l, line) |
||||
|
} |
||||
|
} else { |
||||
|
handle_prompt_command(l, line) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
globals.Exit_In_Progress = true |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// this functions reads all data transferred from daemon or from offline file
|
||||
|
// and plays it here
|
||||
|
// finds which transactions belong to current account
|
||||
|
// and adds them to account for reconciliation
|
||||
|
func blockchain_data_consumer() { |
||||
|
var err error |
||||
|
for { |
||||
|
rlog.Tracef(1, "Discarding old pipe_reader,writer, creating new") |
||||
|
// close already created pipes, discarding there data
|
||||
|
pipe_reader.Close() |
||||
|
pipe_writer.Close() |
||||
|
pipe_reader, pipe_writer = io.Pipe() // create pipes
|
||||
|
|
||||
|
decoder := msgpack.NewDecoder(pipe_reader) |
||||
|
for { |
||||
|
var output globals.TX_Output_Data |
||||
|
|
||||
|
err = decoder.Decode(&output) |
||||
|
if err == io.EOF { // reached eof
|
||||
|
break |
||||
|
} |
||||
|
if err != nil { |
||||
|
fmt.Printf("err while decoding msgpack stream err %s\n", err) |
||||
|
break |
||||
|
} |
||||
|
|
||||
|
if globals.Exit_In_Progress { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
sync_time = time.Now() |
||||
|
if account.Index_Global < output.Index_Global { // process tx if it has not been processed earlier
|
||||
|
|
||||
|
Wallet_Height = output.Height |
||||
|
account.Height = output.Height |
||||
|
if account.Is_Output_Ours(output.Tx_Public_Key, output.Index_within_tx, crypto.Key(output.InKey.Destination)) { |
||||
|
amount, _, result := account.Decode_RingCT_Output(output.Tx_Public_Key, |
||||
|
output.Index_within_tx, |
||||
|
crypto.Key(output.InKey.Mask), |
||||
|
output.ECDHTuple, |
||||
|
output.SigType) |
||||
|
|
||||
|
if result == false { |
||||
|
globals.Logger.Warnf("Internal error occurred, amount cannot be spent") |
||||
|
} |
||||
|
globals.Logger.Infof(color_green+"Height %d transaction %s received %s DERO"+color_white, output.Height, output.TXID, globals.FormatMoney(amount)) |
||||
|
|
||||
|
// add tx to wallet
|
||||
|
account.Add_Transaction_Record_Funds(&output) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// check this keyimage represents our funds
|
||||
|
// if yes we have consumed that specific funds, mark them as such
|
||||
|
amount_spent := uint64(0) |
||||
|
for i := range output.Key_Images { |
||||
|
amount_per_keyimage, result := account.Is_Our_Fund_Consumed(output.Key_Images[i]) |
||||
|
if result { |
||||
|
amount_spent += amount_per_keyimage |
||||
|
account.Consume_Transaction_Record_Funds(&output, output.Key_Images[i]) // decrease fund from our wallet
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if amount_spent > 0 { |
||||
|
globals.Logger.Infof(color_magenta+"Height %d transaction %s Spent %s DERO"+color_white, output.Height, output.TXID, globals.FormatMoney(amount_spent)) |
||||
|
} |
||||
|
|
||||
|
account.Index_Global = output.Index_Global |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// update prompt as and when necessary
|
||||
|
// TODO: make this code simple, with clear direction
|
||||
|
func update_prompt(l *readline.Instance) { |
||||
|
|
||||
|
last_wallet_height := uint64(0) |
||||
|
last_daemon_height := uint64(0) |
||||
|
|
||||
|
for { |
||||
|
time.Sleep(30 * time.Millisecond) // give user a smooth running number
|
||||
|
|
||||
|
if globals.Exit_In_Progress { |
||||
|
return |
||||
|
} |
||||
|
prompt_mutex.Lock() // do not update if we can not lock the mutex
|
||||
|
|
||||
|
// show first 8 bytes of address
|
||||
|
address_trim := "" |
||||
|
if len(address) > 8 { |
||||
|
address_trim = address[0:8] |
||||
|
} else { |
||||
|
address_trim = "DERO Wallet" |
||||
|
} |
||||
|
|
||||
|
if len(address) == 0 { |
||||
|
last_wallet_height = 0 |
||||
|
Wallet_Height = 0 |
||||
|
} |
||||
|
|
||||
|
if !account_valid { |
||||
|
l.SetPrompt(fmt.Sprintf("\033[1m\033[32m%s \033[0m"+color_green+"0/%d \033[32m>>>\033[0m ", address_trim, Daemon_Height)) |
||||
|
prompt_mutex.Unlock() |
||||
|
continue |
||||
|
} |
||||
|
|
||||
|
// only update prompt if needed, trigger resync if required
|
||||
|
if last_wallet_height != Wallet_Height || last_daemon_height != Daemon_Height { |
||||
|
// choose color based on urgency
|
||||
|
color := "\033[32m" // default is green color
|
||||
|
if Wallet_Height < Daemon_Height { |
||||
|
color = "\033[33m" // make prompt yellow
|
||||
|
} |
||||
|
|
||||
|
balance_string := "" |
||||
|
|
||||
|
if account_valid { |
||||
|
balance_unlocked, locked_balance := account.Get_Balance() |
||||
|
balance_string = fmt.Sprintf(color_green+"%s "+color_white+"| "+color_yellow+"%s", globals.FormatMoney(balance_unlocked), globals.FormatMoney(locked_balance)) |
||||
|
} |
||||
|
|
||||
|
l.SetPrompt(fmt.Sprintf("\033[1m\033[32m%s \033[0m"+color+"%d/%d %s\033[32m>>>\033[0m ", address_trim, Wallet_Height, Daemon_Height, balance_string)) |
||||
|
l.Refresh() |
||||
|
last_wallet_height = Wallet_Height |
||||
|
last_daemon_height = Daemon_Height |
||||
|
|
||||
|
} |
||||
|
|
||||
|
if time.Since(sync_time) > (2*time.Second) && Wallet_Height < Daemon_Height { |
||||
|
if !offline_mode { // if offline mode, never connect anywhere
|
||||
|
go Get_Outputs(account.Index_Global, 0) // start sync
|
||||
|
} |
||||
|
|
||||
|
sync_time = time.Now() |
||||
|
} |
||||
|
|
||||
|
prompt_mutex.Unlock() |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// create a new wallet from scratch from random numbers
|
||||
|
func Create_New_Account(l *readline.Instance) *walletapi.Account { |
||||
|
|
||||
|
account, _ := walletapi.Generate_Keys_From_Random() |
||||
|
account.SeedLanguage = choose_seed_language(l) |
||||
|
|
||||
|
// a new account has been created, append the seed to user home directory
|
||||
|
|
||||
|
//usr, err := user.Current()
|
||||
|
/*if err != nil { |
||||
|
globals.Logger.Warnf("Cannot get current username to save recovery key and password") |
||||
|
}else{ // we have a user, get his home dir
|
||||
|
|
||||
|
|
||||
|
}*/ |
||||
|
|
||||
|
return account |
||||
|
} |
||||
|
|
||||
|
// create a new wallet from hex seed provided
|
||||
|
func Create_New_Account_from_seed(l *readline.Instance) *walletapi.Account { |
||||
|
|
||||
|
var account *walletapi.Account |
||||
|
var seedkey crypto.Key |
||||
|
|
||||
|
seed := read_line_with_prompt(l, "Please enter your seed ( hex 64 chars): ") |
||||
|
seed = strings.TrimSpace(seed) // trim any extra space
|
||||
|
seed_raw, err := hex.DecodeString(seed) // hex decode
|
||||
|
if len(seed) != 64 || err != nil { //sanity check
|
||||
|
globals.Logger.Warnf("Seed must be 64 chars hexadecimal chars") |
||||
|
return account |
||||
|
} |
||||
|
|
||||
|
copy(seedkey[:], seed_raw[:32]) // copy bytes to seed
|
||||
|
account, _ = walletapi.Generate_Account_From_Seed(seedkey) // create a new account
|
||||
|
account.SeedLanguage = choose_seed_language(l) // ask user his seed preference and set it
|
||||
|
|
||||
|
account_valid = true |
||||
|
|
||||
|
return account |
||||
|
} |
||||
|
|
||||
|
// create a new wallet from viewable seed provided
|
||||
|
// viewable seed consists of public spend key and private view key
|
||||
|
func Create_New_Account_from_viewable_key(l *readline.Instance) *walletapi.Account { |
||||
|
|
||||
|
var seedkey crypto.Key |
||||
|
var privateview crypto.Key |
||||
|
|
||||
|
var account *walletapi.Account |
||||
|
seed := read_line_with_prompt(l, "Please enter your View Only Key ( hex 128 chars): ") |
||||
|
|
||||
|
seed = strings.TrimSpace(seed) // trim any extra space
|
||||
|
|
||||
|
seed_raw, err := hex.DecodeString(seed) |
||||
|
if len(seed) != 128 || err != nil { |
||||
|
globals.Logger.Warnf("View Only key must be 128 chars hexadecimal chars") |
||||
|
return account |
||||
|
} |
||||
|
|
||||
|
copy(seedkey[:], seed_raw[:32]) |
||||
|
copy(privateview[:], seed_raw[32:64]) |
||||
|
|
||||
|
account, _ = walletapi.Generate_Account_View_Only(seedkey, privateview) |
||||
|
|
||||
|
account_valid = true |
||||
|
|
||||
|
return account |
||||
|
} |
||||
|
|
||||
|
// helper function to let user to choose a seed in specific lanaguage
|
||||
|
func choose_seed_language(l *readline.Instance) string { |
||||
|
languages := mnemonics.Language_List() |
||||
|
fmt.Printf("Language list for seeds, please enter a number (default English)\n") |
||||
|
for i := range languages { |
||||
|
fmt.Fprintf(l.Stderr(), "\033[1m%2d:\033[0m %s\n", i, languages[i]) |
||||
|
} |
||||
|
|
||||
|
language_number := read_line_with_prompt(l, "Please enter a choice: ") |
||||
|
choice := 0 // 0 for english
|
||||
|
|
||||
|
if s, err := strconv.Atoi(language_number); err == nil { |
||||
|
choice = s |
||||
|
} |
||||
|
|
||||
|
for i := range languages { // if user gave any wrong or ot of range choice, choose english
|
||||
|
if choice == i { |
||||
|
return languages[choice] |
||||
|
} |
||||
|
} |
||||
|
// if no match , return Englisg
|
||||
|
return "English" |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// read a line from the prompt
|
||||
|
func read_line_with_prompt(l *readline.Instance, prompt_temporary string) string { |
||||
|
prompt_mutex.Lock() |
||||
|
defer prompt_mutex.Unlock() |
||||
|
l.SetPrompt(prompt_temporary) |
||||
|
line, err := l.Readline() |
||||
|
if err == readline.ErrInterrupt { |
||||
|
if len(line) == 0 { |
||||
|
globals.Logger.Infof("Ctrl-C received, Exiting\n") |
||||
|
os.Exit(0) |
||||
|
} |
||||
|
} else if err == io.EOF { |
||||
|
os.Exit(0) |
||||
|
} |
||||
|
l.SetPrompt(prompt) |
||||
|
return line |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// filter out specfic inputs from input processing
|
||||
|
// currently we only skip CtrlZ background key
|
||||
|
func filterInput(r rune) (rune, bool) { |
||||
|
switch r { |
||||
|
// block CtrlZ feature
|
||||
|
case readline.CharCtrlZ: |
||||
|
return r, false |
||||
|
} |
||||
|
return r, true |
||||
|
} |
@ -0,0 +1,207 @@ |
|||||
|
// 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 main |
||||
|
|
||||
|
import "os" |
||||
|
import "io" |
||||
|
import "fmt" |
||||
|
import "bufio" |
||||
|
import "strings" |
||||
|
import "strconv" |
||||
|
import "compress/gzip" |
||||
|
|
||||
|
import "github.com/chzyer/readline" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/globals" |
||||
|
import "github.com/deroproject/derosuite/walletapi" |
||||
|
|
||||
|
// handle all commands while in prompt mode
|
||||
|
func handle_prompt_command(l *readline.Instance, line string) { |
||||
|
|
||||
|
var err error |
||||
|
line = strings.TrimSpace(line) |
||||
|
line_parts := strings.Fields(line) |
||||
|
|
||||
|
if len(line_parts) < 1 { // if no command return
|
||||
|
return |
||||
|
} |
||||
|
|
||||
|
_ = err |
||||
|
command := "" |
||||
|
if len(line_parts) >= 1 { |
||||
|
command = strings.ToLower(line_parts[0]) |
||||
|
} |
||||
|
|
||||
|
switch command { |
||||
|
case "help": |
||||
|
usage(l.Stderr()) |
||||
|
case "address": // give user his account address
|
||||
|
if account_valid { |
||||
|
fmt.Fprintf(l.Stderr(), "%s\n", account.GetAddress()) |
||||
|
} |
||||
|
case "rescan_bc": // rescan from 0
|
||||
|
fallthrough |
||||
|
case "rescan_spent": // rescan from 0
|
||||
|
if offline_mode { |
||||
|
go trigger_offline_data_scan() |
||||
|
} else { |
||||
|
globals.Logger.Warnf("This command is NOT yet implemented") |
||||
|
} |
||||
|
|
||||
|
case "seed": // give user his seed
|
||||
|
display_seed(l) |
||||
|
case "spendkey": // give user his spend key
|
||||
|
display_spend_key(l) |
||||
|
case "viewkey": // give user his viewkey
|
||||
|
display_view_key(l) |
||||
|
case "walletviewkey": |
||||
|
display_viewwallet_key(l) |
||||
|
|
||||
|
case "set": // set different settings
|
||||
|
case "close": // close the account
|
||||
|
account_valid = false |
||||
|
tmp := &walletapi.Account{} |
||||
|
address = "" |
||||
|
account = tmp // overwrite previous instance
|
||||
|
|
||||
|
case "menu": // enable menu mode
|
||||
|
menu_mode = true |
||||
|
globals.Logger.Infof("Menu mode enabled") |
||||
|
case "bye", "exit", "quit": |
||||
|
globals.Exit_In_Progress = true |
||||
|
|
||||
|
case "": // blank enter key just loop
|
||||
|
default: |
||||
|
fmt.Fprintf(l.Stderr(), "you said: %s", strconv.Quote(line)) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// if we are in offline, scan default or user provided file
|
||||
|
// this function will replay the blockchain data in offline mode
|
||||
|
func trigger_offline_data_scan() { |
||||
|
filename := default_offline_datafile |
||||
|
|
||||
|
if globals.Arguments["--offline_datafile"] != nil { |
||||
|
filename = globals.Arguments["--offline_datafile"].(string) |
||||
|
} |
||||
|
|
||||
|
f, err := os.Open(filename) |
||||
|
if err != nil { |
||||
|
globals.Logger.Warnf("Cannot read offline data file=\"%s\" err: %s ", filename, err) |
||||
|
return |
||||
|
} |
||||
|
w := bufio.NewReader(f) |
||||
|
gzipreader, err := gzip.NewReader(w) |
||||
|
if err != nil { |
||||
|
globals.Logger.Warnf("Error while decompressing offline data file=\"%s\" err: %s ", filename, err) |
||||
|
return |
||||
|
} |
||||
|
defer gzipreader.Close() |
||||
|
io.Copy(pipe_writer, gzipreader) |
||||
|
} |
||||
|
|
||||
|
// this completer is used to complete the commands at the prompt
|
||||
|
// BUG, this needs to be disabled in menu mode
|
||||
|
var completer = readline.NewPrefixCompleter( |
||||
|
readline.PcItem("help"), |
||||
|
readline.PcItem("address"), |
||||
|
readline.PcItem("rescan_bc"), |
||||
|
readline.PcItem("rescan_spent"), |
||||
|
readline.PcItem("print_height"), |
||||
|
readline.PcItem("seed"), |
||||
|
readline.PcItem("menu"), |
||||
|
readline.PcItem("set", |
||||
|
readline.PcItem("priority", |
||||
|
readline.PcItem("lowest x1"), |
||||
|
readline.PcItem("low x4"), |
||||
|
readline.PcItem("normal x8"), |
||||
|
readline.PcItem("high x13"), |
||||
|
readline.PcItem("veryhigh x20"), |
||||
|
), |
||||
|
readline.PcItem("default-ring-size"), |
||||
|
readline.PcItem("store-tx-info"), |
||||
|
readline.PcItem("ask-password"), |
||||
|
), |
||||
|
readline.PcItem("spendkey"), |
||||
|
readline.PcItem("viewkey"), |
||||
|
readline.PcItem("walletviewkey"), |
||||
|
readline.PcItem("bye"), |
||||
|
readline.PcItem("exit"), |
||||
|
readline.PcItem("quit"), |
||||
|
) |
||||
|
|
||||
|
// help command screen
|
||||
|
func usage(w io.Writer) { |
||||
|
io.WriteString(w, "commands:\n") |
||||
|
io.WriteString(w, "\t\033[1mhelp\033[0m\t\tthis help\n") |
||||
|
io.WriteString(w, "\t\033[1maddress\033[0m\t\tDisplay user address\n") |
||||
|
io.WriteString(w, "\t\033[1mmenu\033[0m\t\tEnable menu mode\n") |
||||
|
io.WriteString(w, "\t\033[1mrescan_bc\033[0m\tRescan blockchain again from 0 height\n") |
||||
|
io.WriteString(w, "\t\033[1mprint_block\033[0m\tPrint block, print_block <block_hash> or <block_height>\n") |
||||
|
io.WriteString(w, "\t\033[1mseed\033[0m\tDisplay seed\n") |
||||
|
io.WriteString(w, "\t\033[1mset\033[0m\tSet various settings\n") |
||||
|
io.WriteString(w, "\t\033[1mstatus\033[0m\t\tShow genereal information\n") |
||||
|
io.WriteString(w, "\t\033[1mspendkey\033[0m\tView secret key\n") |
||||
|
io.WriteString(w, "\t\033[1mviewkey\033[0m\tView view key\n") |
||||
|
io.WriteString(w, "\t\033[1mwalletviewkey\033[0m\tWallet view key, used to create watchable view only wallet\n") |
||||
|
io.WriteString(w, "\t\033[1mbye\033[0m\t\tQuit wallet\n") |
||||
|
io.WriteString(w, "\t\033[1mexit\033[0m\t\tQuit wallet\n") |
||||
|
io.WriteString(w, "\t\033[1mquit\033[0m\t\tQuit wallet\n") |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// display seed to the user in his preferred language
|
||||
|
func display_seed(l *readline.Instance) { |
||||
|
if account_valid { |
||||
|
seed := account.GetSeed() |
||||
|
fmt.Fprintf(l.Stderr(), color_green+"PLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control."+color_white+"\n") |
||||
|
fmt.Fprintf(os.Stderr, color_red+"%s"+color_white+"\n", seed) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// display spend key
|
||||
|
// viewable wallet do not have spend secret key
|
||||
|
// TODO wee need to give user a warning if we are printing secret
|
||||
|
func display_spend_key(l *readline.Instance) { |
||||
|
if account_valid { |
||||
|
if !account.ViewOnly { |
||||
|
fmt.Fprintf(os.Stderr, "spend key secret : "+color_red+"%s"+color_white+"\n", account.Keys.Spendkey_Secret) |
||||
|
} |
||||
|
fmt.Fprintf(os.Stderr, "spend key public : %s\n", account.Keys.Spendkey_Public) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//display view key
|
||||
|
func display_view_key(l *readline.Instance) { |
||||
|
if account_valid { |
||||
|
fmt.Fprintf(os.Stderr, "view key secret : "+color_yellow+"%s"+color_white+"\n", account.Keys.Viewkey_Secret) |
||||
|
fmt.Fprintf(os.Stderr, "view key public : %s\n", account.Keys.Viewkey_Public) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// display wallet view only Keys
|
||||
|
// this will create a watchable view only mode
|
||||
|
func display_viewwallet_key(l *readline.Instance) { |
||||
|
if account_valid { |
||||
|
io.WriteString(l.Stderr(), fmt.Sprintf("This Key can used to create a watch only wallet. This wallet can only see incoming funds but cannot spend them.\nThe key is below.\n%s\n\n", account.GetViewWalletKey())) |
||||
|
} |
||||
|
|
||||
|
} |
@ -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. |
||||
|
|
@ -1,8 +1,12 @@ |
|||||
|
// 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
|
||||
|
|
||||
package main |
package main |
||||
|
|
||||
import "testing" |
import "testing" |
||||
|
|
||||
|
func Test_Part1(t *testing.T) { |
||||
|
|
||||
func Test_Part1(t *testing.T){ |
|
||||
|
|
||||
} |
} |
@ -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,12 @@ |
|||||
|
// 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
|
||||
|
|
||||
|
package main |
||||
|
|
||||
|
import "testing" |
||||
|
|
||||
|
func Test_Part1(t *testing.T) { |
||||
|
|
||||
|
} |
@ -0,0 +1,673 @@ |
|||||
|
// 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 main |
||||
|
|
||||
|
// this file implements the explorer for DERO blockchain
|
||||
|
// this needs only RPC access
|
||||
|
// NOTE: Only use data exported from within the RPC interface, do direct use of exported variables fom packages
|
||||
|
// NOTE: we can use structs defined within the RPCserver package
|
||||
|
// This is being developed to track down and confirm some bugs
|
||||
|
// NOTE: This is NO longer entirely compliant with the xyz RPC interface ( the pool part is not compliant), currently and can be used as it for their chain,
|
||||
|
// atleast for the last 1 year
|
||||
|
|
||||
|
// TODO: error handling is non-existant ( as this was built up in hrs ). Add proper error handling
|
||||
|
//
|
||||
|
|
||||
|
import "time" |
||||
|
import "fmt" |
||||
|
import "net" |
||||
|
import "bytes" |
||||
|
import "strings" |
||||
|
import "encoding/hex" |
||||
|
import "net/http" |
||||
|
import "html/template" |
||||
|
import "encoding/json" |
||||
|
import "io/ioutil" |
||||
|
|
||||
|
import "github.com/docopt/docopt-go" |
||||
|
import log "github.com/sirupsen/logrus" |
||||
|
import "github.com/ybbus/jsonrpc" |
||||
|
|
||||
|
import "github.com/deroproject/derosuite/block" |
||||
|
import "github.com/deroproject/derosuite/crypto" |
||||
|
import "github.com/deroproject/derosuite/transaction" |
||||
|
import "github.com/deroproject/derosuite/blockchain/rpcserver" |
||||
|
|
||||
|
var command_line string = `dero_explorer |
||||
|
DERO Explorer: A secure, private blockchain with smart-contracts |
||||
|
|
||||
|
Usage: |
||||
|
dero_explorer [--help] [--version] [--debug] [--rpc-server-address=<127.0.0.1:18091>] [--http-address=<0.0.0.0:8080>] |
||||
|
dero_explorer -h | --help |
||||
|
dero_explorer --version |
||||
|
|
||||
|
Options: |
||||
|
-h --help Show this screen. |
||||
|
--version Show version. |
||||
|
--debug Debug mode enabled, print log messages |
||||
|
--rpc-server-address=<127.0.0.1:18091> connect to this daemon port as client |
||||
|
--http-address=<0.0.0.0:8080> explorer listens on this port to serve user requests` |
||||
|
|
||||
|
var rpcClient *jsonrpc.RPCClient |
||||
|
var netClient *http.Client |
||||
|
var endpoint string |
||||
|
var replacer = strings.NewReplacer("h", ":", "m", ":", "s", "") |
||||
|
|
||||
|
func main() { |
||||
|
var err error |
||||
|
var arguments map[string]interface{} |
||||
|
|
||||
|
arguments, err = docopt.Parse(command_line, nil, true, "DERO Explorer : work in progress", false) |
||||
|
|
||||
|
if err != nil { |
||||
|
log.Fatalf("Error while parsing options err: %s\n", err) |
||||
|
} |
||||
|
|
||||
|
if arguments["--debug"].(bool) == true { |
||||
|
log.SetLevel(log.DebugLevel) |
||||
|
} |
||||
|
|
||||
|
log.Debugf("Arguments %+v", arguments) |
||||
|
log.Infof("DERO Exporer : This is under heavy development, use it for testing/evaluations purpose only") |
||||
|
log.Infof("Copyright 2017-2018 DERO Project. All rights reserved.") |
||||
|
endpoint = "127.0.0.1:9999" |
||||
|
if arguments["--rpc-server-address"] != nil { |
||||
|
endpoint = arguments["--rpc-server-address"].(string) |
||||
|
} |
||||
|
|
||||
|
log.Infof("using RPC endpoint %s", endpoint) |
||||
|
|
||||
|
listen_address := "0.0.0.0:8080" |
||||
|
if arguments["--http-address"] != nil { |
||||
|
listen_address = arguments["--http-address"].(string) |
||||
|
} |
||||
|
log.Infof("Will listen on %s", listen_address) |
||||
|
|
||||
|
// create client
|
||||
|
rpcClient = jsonrpc.NewRPCClient("http://" + endpoint + "/json_rpc") |
||||
|
|
||||
|
var netTransport = &http.Transport{ |
||||
|
Dial: (&net.Dialer{ |
||||
|
Timeout: 5 * time.Second, |
||||
|
}).Dial, |
||||
|
TLSHandshakeTimeout: 5 * time.Second, |
||||
|
} |
||||
|
|
||||
|
netClient = &http.Client{ |
||||
|
Timeout: time.Second * 10, |
||||
|
Transport: netTransport, |
||||
|
} |
||||
|
|
||||
|
// execute rpc to service
|
||||
|
response, err := rpcClient.Call("get_info") |
||||
|
|
||||
|
if err == nil { |
||||
|
log.Infof("Connection to RPC server successful") |
||||
|
} else { |
||||
|
log.Fatalf("Connection to RPC server Failed err %s", err) |
||||
|
} |
||||
|
var info rpcserver.GetInfo_Result |
||||
|
err = response.GetObject(&info) |
||||
|
|
||||
|
fmt.Printf("%+v err %s\n", info, err) |
||||
|
|
||||
|
http.HandleFunc("/search", search_handler) |
||||
|
http.HandleFunc("/page/", page_handler) |
||||
|
http.HandleFunc("/block/", block_handler) |
||||
|
http.HandleFunc("/txpool/", txpool_handler) |
||||
|
http.HandleFunc("/tx/", tx_handler) |
||||
|
http.HandleFunc("/", root_handler) |
||||
|
|
||||
|
fmt.Printf("Listening for requests\n") |
||||
|
err = http.ListenAndServe(listen_address, nil) |
||||
|
log.Warnf("Listening to port %s err : %s", listen_address, err) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// all the tx info which ever needs to be printed
|
||||
|
type txinfo struct { |
||||
|
Height string // height at which tx was mined
|
||||
|
Depth uint64 |
||||
|
Timestamp uint64 // timestamp
|
||||
|
Age string // time diff from current time
|
||||
|
Block_time string // UTC time from block header
|
||||
|
Epoch uint64 // Epoch time
|
||||
|
In_Pool bool // whether tx was in pool
|
||||
|
Hash string // hash for hash
|
||||
|
PrefixHash string // prefix hash
|
||||
|
Version int // version of tx
|
||||
|
Size string // size of tx in KB
|
||||
|
Sizeuint64 uint64 // size of tx in bytes
|
||||
|
Fee string // fee in TX
|
||||
|
Feeuint64 uint64 // fee in atomic units
|
||||
|
In int // inputs counts
|
||||
|
Out int // outputs counts
|
||||
|
Amount string |
||||
|
CoinBase bool // is tx coin base
|
||||
|
Extra string // extra within tx
|
||||
|
Keyimages []string // key images within tx
|
||||
|
OutAddress []string // contains output secret key
|
||||
|
OutOffset []uint64 // contains index offsets
|
||||
|
Type string // ringct or ruffct ( bulletproof)
|
||||
|
Ring_size int |
||||
|
} |
||||
|
|
||||
|
// any information for block which needs to be printed
|
||||
|
type block_info struct { |
||||
|
Major_Version uint64 |
||||
|
Minor_Version uint64 |
||||
|
Height uint64 |
||||
|
Depth uint64 |
||||
|
Timestamp uint64 |
||||
|
Hash string |
||||
|
Prev_Hash string |
||||
|
Nonce uint64 |
||||
|
Fees string |
||||
|
Reward string |
||||
|
Size string |
||||
|
Age string // time diff from current time
|
||||
|
Block_time string // UTC time from block header
|
||||
|
Epoch uint64 // Epoch time
|
||||
|
Outputs string |
||||
|
Mtx txinfo |
||||
|
Txs []txinfo |
||||
|
Orphan_Status bool |
||||
|
Tx_Count int |
||||
|
} |
||||
|
|
||||
|
// load and setup block_info from rpc
|
||||
|
// if hash is less than 64 bytes then it is considered a height parameter
|
||||
|
func load_block_from_rpc(info *block_info, block_hash string, recursive bool) (err error) { |
||||
|
var bl block.Block |
||||
|
var bresult rpcserver.GetBlock_Result |
||||
|
|
||||
|
var block_height int |
||||
|
var block_bin []byte |
||||
|
if len(block_hash) != 64 { // parameter is a height
|
||||
|
fmt.Sscanf(block_hash, "%d", &block_height) |
||||
|
// user requested block height
|
||||
|
log.Debugf("User requested block at height %d user input %s", block_height, block_hash) |
||||
|
response, err := rpcClient.CallNamed("getblock", map[string]interface{}{"height": uint64(block_height)}) |
||||
|
|
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
err = response.GetObject(&bresult) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
} else { // parameter is the hex blob
|
||||
|
|
||||
|
log.Debugf("User requested block %s", block_hash) |
||||
|
response, err := rpcClient.CallNamed("getblock", map[string]interface{}{"hash": block_hash}) |
||||
|
|
||||
|
if err != nil { |
||||
|
log.Warnf("err %s ", err) |
||||
|
return err |
||||
|
} |
||||
|
if response.Error != nil { |
||||
|
log.Warnf("err %s ", response.Error) |
||||
|
return fmt.Errorf("No Such block or other Error") |
||||
|
} |
||||
|
|
||||
|
err = response.GetObject(&bresult) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// fmt.Printf("block %d %+v\n",i, bresult)
|
||||
|
info.Height = bresult.Block_Header.Height |
||||
|
info.Depth = bresult.Block_Header.Depth |
||||
|
|
||||
|
duration_second := (uint64(time.Now().UTC().Unix()) - bresult.Block_Header.Timestamp) |
||||
|
info.Age = replacer.Replace((time.Duration(duration_second) * time.Second).String()) |
||||
|
info.Block_time = time.Unix(int64(bresult.Block_Header.Timestamp), 0).Format("2006-01-02 15:04:05") |
||||
|
info.Epoch = bresult.Block_Header.Timestamp |
||||
|
info.Outputs = fmt.Sprintf("%.03f", float32(bresult.Block_Header.Reward)/1000000000000.0) |
||||
|
info.Size = "N/A" |
||||
|
info.Hash = bresult.Block_Header.Hash |
||||
|
info.Prev_Hash = bresult.Block_Header.Prev_Hash |
||||
|
info.Orphan_Status = bresult.Block_Header.Orphan_Status |
||||
|
info.Nonce = bresult.Block_Header.Nonce |
||||
|
info.Major_Version = bresult.Block_Header.Major_Version |
||||
|
info.Minor_Version = bresult.Block_Header.Minor_Version |
||||
|
info.Reward = fmt.Sprintf("%.03f", float32(bresult.Block_Header.Reward)/1000000000000.0) |
||||
|
|
||||
|
block_bin, _ = hex.DecodeString(bresult.Blob) |
||||
|
bl.Deserialize(block_bin) |
||||
|
|
||||
|
if recursive { |
||||
|
// fill in miner tx info
|
||||
|
|
||||
|
err = load_tx_from_rpc(&info.Mtx, bl.Miner_tx.GetHash().String()) //TODO handle error
|
||||
|
|
||||
|
info.Tx_Count = len(bl.Tx_hashes) |
||||
|
|
||||
|
fees := uint64(0) |
||||
|
size := uint64(0) |
||||
|
// if we have any other tx load them also
|
||||
|
for i := 0; i < len(bl.Tx_hashes); i++ { |
||||
|
var tx txinfo |
||||
|
err = load_tx_from_rpc(&tx, bl.Tx_hashes[i].String()) //TODO handle error
|
||||
|
info.Txs = append(info.Txs, tx) |
||||
|
fees += tx.Feeuint64 |
||||
|
size += tx.Sizeuint64 |
||||
|
} |
||||
|
|
||||
|
info.Fees = fmt.Sprintf("%.03f", float32(fees)/1000000000000.0) |
||||
|
info.Size = fmt.Sprintf("%.03f", float32(size)/1024) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// this will fill up the info struct from the tx
|
||||
|
func load_tx_info_from_tx(info *txinfo, tx *transaction.Transaction) (err error) { |
||||
|
info.Hash = tx.GetHash().String() |
||||
|
info.PrefixHash = tx.GetPrefixHash().String() |
||||
|
info.Size = fmt.Sprintf("%.03f", float32(len(tx.Serialize()))/1024) |
||||
|
info.Sizeuint64 = uint64(len(tx.Serialize())) |
||||
|
info.Version = int(tx.Version) |
||||
|
info.Extra = fmt.Sprintf("%x", tx.Extra) |
||||
|
info.In = len(tx.Vin) |
||||
|
info.Out = len(tx.Vout) |
||||
|
|
||||
|
if !tx.IsCoinbase() { |
||||
|
info.Fee = fmt.Sprintf("%.012f", float64(tx.RctSignature.Get_TX_Fee())/1000000000000) |
||||
|
info.Feeuint64 = tx.RctSignature.Get_TX_Fee() |
||||
|
info.Amount = "?" |
||||
|
|
||||
|
info.Ring_size = len(tx.Vin[0].(transaction.Txin_to_key).Key_offsets) |
||||
|
for i := 0; i < len(tx.Vin); i++ { |
||||
|
info.Keyimages = append(info.Keyimages, fmt.Sprintf("%s ring members %+v", tx.Vin[i].(transaction.Txin_to_key).K_image, tx.Vin[i].(transaction.Txin_to_key).Key_offsets)) |
||||
|
} |
||||
|
} else { |
||||
|
info.CoinBase = true |
||||
|
info.In = 0 |
||||
|
info.Amount = fmt.Sprintf("%.012f", float64(tx.Vout[0].Amount)/1000000000000) |
||||
|
} |
||||
|
|
||||
|
for i := 0; i < len(tx.Vout); i++ { |
||||
|
info.OutAddress = append(info.OutAddress, tx.Vout[i].Target.(transaction.Txout_to_key).Key.String()) |
||||
|
} |
||||
|
|
||||
|
// if outputs cannot be located, do not panic
|
||||
|
// this will be the case for pool transactions
|
||||
|
if len(info.OutAddress) != len(info.OutOffset) { |
||||
|
info.OutOffset = make([]uint64, len(info.OutAddress), len(info.OutAddress)) |
||||
|
} |
||||
|
|
||||
|
switch tx.RctSignature.Get_Sig_Type() { |
||||
|
case 0: |
||||
|
info.Type = "RingCT/0" |
||||
|
case 1: |
||||
|
info.Type = "RingCT/1 MG" |
||||
|
case 2: |
||||
|
info.Type = "RingCT/2 Simple" |
||||
|
} |
||||
|
|
||||
|
if !info.In_Pool { // find the age of block and other meta
|
||||
|
var blinfo block_info |
||||
|
err := load_block_from_rpc(&blinfo, fmt.Sprintf("%s", info.Height), false) // we only need block data and not data of txs
|
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
// fmt.Printf("Blinfo %+v height %d", blinfo, info.Height);
|
||||
|
|
||||
|
info.Age = blinfo.Age |
||||
|
info.Block_time = blinfo.Block_time |
||||
|
info.Epoch = blinfo.Epoch |
||||
|
info.Timestamp = blinfo.Epoch |
||||
|
info.Depth = blinfo.Depth |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// load and setup txinfo from rpc
|
||||
|
func load_tx_from_rpc(info *txinfo, txhash string) (err error) { |
||||
|
var tx_params rpcserver.GetTransaction_Params |
||||
|
var tx_result rpcserver.GetTransaction_Result |
||||
|
|
||||
|
//fmt.Printf("Requesting tx data %s", txhash);
|
||||
|
tx_params.Tx_Hashes = append(tx_params.Tx_Hashes, txhash) |
||||
|
|
||||
|
request_bytes, err := json.Marshal(&tx_params) |
||||
|
response, err := http.Post("http://"+endpoint+"/gettransactions", "application/json", bytes.NewBuffer(request_bytes)) |
||||
|
if err != nil { |
||||
|
//fmt.Printf("err while requesting tx err %s",err);
|
||||
|
return |
||||
|
} |
||||
|
buf, err := ioutil.ReadAll(response.Body) |
||||
|
if err != nil { |
||||
|
// fmt.Printf("err while reading reponse body err %s",err);
|
||||
|
return |
||||
|
} |
||||
|
|
||||
|
err = json.Unmarshal(buf, &tx_result) |
||||
|
if err != nil { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// fmt.Printf("TX response %+v", tx_result)
|
||||
|
|
||||
|
if tx_result.Status != "OK" { |
||||
|
return fmt.Errorf("No Such TX RPC error status %s", tx_result.Status) |
||||
|
} |
||||
|
|
||||
|
var tx transaction.Transaction |
||||
|
|
||||
|
if len(tx_result.Txs_as_hex[0]) < 50 { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
tx_bin, _ := hex.DecodeString(tx_result.Txs_as_hex[0]) |
||||
|
tx.DeserializeHeader(tx_bin) |
||||
|
|
||||
|
// fill as much info required from headers
|
||||
|
if tx_result.Txs[0].In_pool { |
||||
|
info.In_Pool = true |
||||
|
} else { |
||||
|
info.Height = fmt.Sprintf("%d", tx_result.Txs[0].Block_Height) |
||||
|
} |
||||
|
|
||||
|
for x := range tx_result.Txs[0].Output_Indices { |
||||
|
info.OutOffset = append(info.OutOffset, tx_result.Txs[0].Output_Indices[x]) |
||||
|
} |
||||
|
|
||||
|
//fmt.Printf("tx_result %+v\n",tx_result.Txs)
|
||||
|
|
||||
|
return load_tx_info_from_tx(info, &tx) |
||||
|
} |
||||
|
|
||||
|
func block_handler(w http.ResponseWriter, r *http.Request) { |
||||
|
param := "" |
||||
|
fmt.Sscanf(r.URL.EscapedPath(), "/block/%s", ¶m) |
||||
|
|
||||
|
var blinfo block_info |
||||
|
err := load_block_from_rpc(&blinfo, param, true) |
||||
|
_ = err |
||||
|
|
||||
|
// execute template now
|
||||
|
data := map[string]interface{}{} |
||||
|
|
||||
|
data["title"] = "DERO BlockChain Explorer (Golang)" |
||||
|
data["servertime"] = time.Now().UTC().Format("2006-01-02 15:04:05") |
||||
|
data["block"] = blinfo |
||||
|
|
||||
|
t, err := template.New("foo").Parse(header_template + block_template + footer_template) |
||||
|
|
||||
|
err = t.ExecuteTemplate(w, "block", data) |
||||
|
if err != nil { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
return |
||||
|
|
||||
|
// fmt.Fprint(w, "This is a valid block")
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
func tx_handler(w http.ResponseWriter, r *http.Request) { |
||||
|
var info txinfo |
||||
|
tx_hex := "" |
||||
|
fmt.Sscanf(r.URL.EscapedPath(), "/tx/%s", &tx_hex) |
||||
|
txhash := crypto.HashHexToHash(tx_hex) |
||||
|
log.Debugf("user requested TX %s", tx_hex) |
||||
|
|
||||
|
err := load_tx_from_rpc(&info, txhash.String()) //TODO handle error
|
||||
|
_ = err |
||||
|
|
||||
|
// execute template now
|
||||
|
data := map[string]interface{}{} |
||||
|
|
||||
|
data["title"] = "DERO BlockChain Explorer (Golang)" |
||||
|
data["servertime"] = time.Now().UTC().Format("2006-01-02 15:04:05") |
||||
|
data["info"] = info |
||||
|
|
||||
|
t, err := template.New("foo").Parse(header_template + tx_template + footer_template) |
||||
|
|
||||
|
err = t.ExecuteTemplate(w, "tx", data) |
||||
|
if err != nil { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
return |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func pool_handler(w http.ResponseWriter, r *http.Request) { |
||||
|
|
||||
|
fmt.Fprint(w, "This is a valid pool") |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// if there is any error, we return back empty
|
||||
|
// if pos is wrong we return back
|
||||
|
// pos is descending order
|
||||
|
func fill_tx_structure(pos int, size_in_blocks int) (data []block_info) { |
||||
|
|
||||
|
for i := pos; i > (pos-11) && i >= 0; i-- { // query blocks by height
|
||||
|
var blinfo block_info |
||||
|
err := load_block_from_rpc(&blinfo, fmt.Sprintf("%d", i), true) |
||||
|
if err == nil { |
||||
|
data = append(data, blinfo) |
||||
|
} |
||||
|
} |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
func show_page(w http.ResponseWriter, page int) { |
||||
|
data := map[string]interface{}{} |
||||
|
var info rpcserver.GetInfo_Result |
||||
|
|
||||
|
data["title"] = "DERO BlockChain Explorer (Golang)" |
||||
|
data["servertime"] = time.Now().UTC().Format("2006-01-02 15:04:05") |
||||
|
|
||||
|
t, err := template.New("foo").Parse(header_template + txpool_template + main_template + paging_template + footer_template) |
||||
|
|
||||
|
// collect all the data afresh
|
||||
|
// execute rpc to service
|
||||
|
response, err := rpcClient.Call("get_info") |
||||
|
|
||||
|
if err != nil { |
||||
|
goto exit_error |
||||
|
} |
||||
|
|
||||
|
err = response.GetObject(&info) |
||||
|
if err != nil { |
||||
|
goto exit_error |
||||
|
} |
||||
|
|
||||
|
//fmt.Printf("get info %+v", info)
|
||||
|
|
||||
|
data["Network_Difficulty"] = info.Difficulty |
||||
|
data["hash_rate"] = fmt.Sprintf("%.03f", float32(info.Difficulty/1000000)/float32(info.Target)) |
||||
|
data["txpool_size"] = info.Tx_pool_size |
||||
|
data["testnet"] = info.Testnet |
||||
|
|
||||
|
if int(info.Height) < page*11 { // use requested invalid page, give page 0
|
||||
|
page = 0 |
||||
|
} |
||||
|
|
||||
|
data["previous_page"] = 0 |
||||
|
if page > 0 { |
||||
|
data["previous_page"] = page - 1 |
||||
|
} |
||||
|
data["current_page"] = page |
||||
|
data["total_page"] = int(info.Height) / 11 |
||||
|
|
||||
|
data["next_page"] = page + 1 |
||||
|
if (page + 1) > int(info.Height)/11 { |
||||
|
data["next_page"] = page |
||||
|
} |
||||
|
|
||||
|
fill_tx_pool_info(data, 25) |
||||
|
|
||||
|
data["block_array"] = fill_tx_structure(int(info.Height)-(page*11), 11) |
||||
|
|
||||
|
err = t.ExecuteTemplate(w, "main", data) |
||||
|
if err != nil { |
||||
|
goto exit_error |
||||
|
} |
||||
|
|
||||
|
return |
||||
|
|
||||
|
exit_error: |
||||
|
fmt.Fprintf(w, "Error occurred err %s", err) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func txpool_handler(w http.ResponseWriter, r *http.Request) { |
||||
|
data := map[string]interface{}{} |
||||
|
var info rpcserver.GetInfo_Result |
||||
|
|
||||
|
data["title"] = "DERO BlockChain Explorer (Golang)" |
||||
|
data["servertime"] = time.Now().UTC().Format("2006-01-02 15:04:05") |
||||
|
|
||||
|
|
||||
|
t, err := template.New("foo").Parse(header_template + txpool_template + main_template + paging_template + footer_template + txpool_page_template) |
||||
|
|
||||
|
// collect all the data afresh
|
||||
|
// execute rpc to service
|
||||
|
response, err := rpcClient.Call("get_info") |
||||
|
|
||||
|
if err != nil { |
||||
|
goto exit_error |
||||
|
} |
||||
|
|
||||
|
err = response.GetObject(&info) |
||||
|
if err != nil { |
||||
|
goto exit_error |
||||
|
} |
||||
|
|
||||
|
//fmt.Printf("get info %+v", info)
|
||||
|
|
||||
|
data["Network_Difficulty"] = info.Difficulty |
||||
|
data["hash_rate"] = fmt.Sprintf("%.03f", float32(info.Difficulty/1000000)/float32(info.Target)) |
||||
|
data["txpool_size"] = info.Tx_pool_size |
||||
|
data["testnet"] = info.Testnet |
||||
|
|
||||
|
fill_tx_pool_info(data, 500) // show only 500 txs
|
||||
|
|
||||
|
err = t.ExecuteTemplate(w, "txpool_page", data) |
||||
|
if err != nil { |
||||
|
goto exit_error |
||||
|
} |
||||
|
|
||||
|
return |
||||
|
|
||||
|
exit_error: |
||||
|
fmt.Fprintf(w, "Error occurred err %s", err) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// shows a page
|
||||
|
func page_handler(w http.ResponseWriter, r *http.Request) { |
||||
|
page := 0 |
||||
|
page_string := r.URL.EscapedPath() |
||||
|
fmt.Sscanf(page_string, "/page/%d", &page) |
||||
|
log.Debugf("user requested page %d", page) |
||||
|
show_page(w, page) |
||||
|
} |
||||
|
|
||||
|
// root shows page 0
|
||||
|
func root_handler(w http.ResponseWriter, r *http.Request) { |
||||
|
log.Debugf("Showing main page") |
||||
|
show_page(w, 0) |
||||
|
} |
||||
|
|
||||
|
// search handler, finds the items using rpc bruteforce
|
||||
|
func search_handler(w http.ResponseWriter, r *http.Request) { |
||||
|
log.Debugf("Showing search page") |
||||
|
|
||||
|
values, ok := r.URL.Query()["value"] |
||||
|
|
||||
|
if !ok || len(values) < 1 { |
||||
|
show_page(w, 0) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// Query()["key"] will return an array of items,
|
||||
|
// we only want the single item.
|
||||
|
value := values[0] |
||||
|
|
||||
|
// check whether the page is block or tx or height
|
||||
|
var blinfo block_info |
||||
|
var tx txinfo |
||||
|
err := load_block_from_rpc(&blinfo, value, false) |
||||
|
if err == nil { |
||||
|
log.Debugf("Redirecting user to block page") |
||||
|
http.Redirect(w, r, "/block/"+value, 302) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
err = load_tx_from_rpc(&tx, value) //TODO handle error
|
||||
|
if err == nil { |
||||
|
log.Debugf("Redirecting user to tx page") |
||||
|
http.Redirect(w, r, "/tx/"+value, 302) |
||||
|
|
||||
|
return |
||||
|
} |
||||
|
|
||||
|
show_page(w, 0) |
||||
|
return |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// fill all the tx pool info as per requested
|
||||
|
func fill_tx_pool_info(data map[string]interface{}, max_count int) error { |
||||
|
|
||||
|
var txs []txinfo |
||||
|
var txpool rpcserver.GetTxPool_Result |
||||
|
|
||||
|
data["mempool"] = txs // initialize with empty data
|
||||
|
// collect all the data afresh
|
||||
|
// execute rpc to service
|
||||
|
response, err := rpcClient.Call("gettxpool") |
||||
|
|
||||
|
if err != nil { |
||||
|
return fmt.Errorf("gettxpool rpc failed") |
||||
|
} |
||||
|
|
||||
|
err = response.GetObject(&txpool) |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("gettxpool rpc failed") |
||||
|
} |
||||
|
|
||||
|
for i := range txpool.Tx_list { |
||||
|
var info txinfo |
||||
|
err := load_tx_from_rpc(&info, txpool.Tx_list[i]) //TODO handle error
|
||||
|
if err != nil { |
||||
|
continue |
||||
|
} |
||||
|
txs = append(txs, info) |
||||
|
|
||||
|
if len(txs) >= max_count { |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
data["mempool"] = txs |
||||
|
return nil |
||||
|
|
||||
|
} |
@ -0,0 +1,489 @@ |
|||||
|
// 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 main |
||||
|
|
||||
|
// this files defines all the templates
|
||||
|
|
||||
|
var header_template string = ` |
||||
|
{{define "header"}} |
||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE"> |
||||
|
<title>{{ .title }}</title> |
||||
|
<!--<link rel="stylesheet" type="text/css" href="/css/style.css">--> |
||||
|
<style type="text/css"> |
||||
|
body { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
color: green; |
||||
|
background-color: white; |
||||
|
} |
||||
|
|
||||
|
h1, h2, h3, h4, h5, h6 { |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.center { |
||||
|
margin: auto; |
||||
|
width: 96%; |
||||
|
/*border: 1px solid #73AD21; |
||||
|
padding: 10px;*/ |
||||
|
} |
||||
|
|
||||
|
tr, li, #pages, .info { |
||||
|
font-family: "Lucida Console", Monaco, monospace; |
||||
|
font-size : 12px; |
||||
|
height: 22px; |
||||
|
} |
||||
|
|
||||
|
#pages |
||||
|
{ |
||||
|
margin-top: 15px; |
||||
|
} |
||||
|
|
||||
|
td { |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
a:link { |
||||
|
text-decoration: none; |
||||
|
color: blue; |
||||
|
} |
||||
|
|
||||
|
a:visited { |
||||
|
text-decoration: none; |
||||
|
color: blue; |
||||
|
} |
||||
|
|
||||
|
a:hover { |
||||
|
text-decoration: underline; |
||||
|
color: blue; |
||||
|
} |
||||
|
|
||||
|
a:active { |
||||
|
text-decoration: none; |
||||
|
color: blue; |
||||
|
} |
||||
|
|
||||
|
form { |
||||
|
display: inline-block; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.style-1 input[type="text"] { |
||||
|
padding: 2px; |
||||
|
border: solid 1px #dcdcdc; |
||||
|
transition: box-shadow 0.3s, border 0.3s; |
||||
|
} |
||||
|
.style-1 input[type="text"]:focus, |
||||
|
.style-1 input[type="text"].focus { |
||||
|
border: solid 1px #707070; |
||||
|
box-shadow: 0 0 5px 1px #969696; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.tabs { |
||||
|
position: relative; |
||||
|
min-height: 220px; /* This part sucks */ |
||||
|
clear: both; |
||||
|
margin: 25px 0; |
||||
|
} |
||||
|
|
||||
|
.tab { |
||||
|
float: left; |
||||
|
} |
||||
|
|
||||
|
.tab label { |
||||
|
background: white; |
||||
|
padding: 10px; |
||||
|
border: 1px solid #ccc; |
||||
|
margin-left: -1px; |
||||
|
position: relative; |
||||
|
left: 1px; |
||||
|
} |
||||
|
|
||||
|
.tab [type=radio] { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.content { |
||||
|
position: absolute; |
||||
|
top: 28px; |
||||
|
left: 0; |
||||
|
background: white; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
padding: 20px; |
||||
|
border: 1px solid #ccc; |
||||
|
} |
||||
|
|
||||
|
[type=radio]:checked ~ label { |
||||
|
background: #505050 ; |
||||
|
border-bottom: 1px solid green; |
||||
|
z-index: 2; |
||||
|
} |
||||
|
|
||||
|
[type=radio]:checked ~ label ~ .content { |
||||
|
z-index: 1; |
||||
|
} |
||||
|
|
||||
|
input#toggle-1[type=checkbox] { |
||||
|
position: absolute; |
||||
|
/*top: -9999px;*/ |
||||
|
left: -9999px; |
||||
|
|
||||
|
} |
||||
|
label#show-decoded-inputs { |
||||
|
/*-webkit-appearance: push-button;*/ |
||||
|
/*-moz-appearance: button;*/ |
||||
|
display: inline-block; |
||||
|
/*margin: 60px 0 10px 0;*/ |
||||
|
cursor: pointer; |
||||
|
background-color: white;; |
||||
|
color: green; |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
div#decoded-inputs{ |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
/* Toggled State */ |
||||
|
input#toggle-1[type=checkbox]:checked ~ div#decoded-inputs { |
||||
|
display: block; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
</head> |
||||
|
<body> |
||||
|
<div> |
||||
|
|
||||
|
<div class="center"> |
||||
|
<h1 class="center"><a href="/">{{ .title }} {{if .testnet}} TestNet {{end}}</a></h1> |
||||
|
<!-- <h4 style="font-size: 15px; margin: 0px">(no javascript - no cookies - no web analytics trackers - no images - open sourced)</h4> --> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="center"> |
||||
|
<form action="/search" method="get" style="width:100%; margin-top:15px" class="style-1"> |
||||
|
<input type="text" name="value" size="120" |
||||
|
placeholder="block height, block hash, transaction hash"> |
||||
|
<input type="submit" value="Search"> |
||||
|
</form> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
{{if .Network_Difficulty}} |
||||
|
<div class="center"> |
||||
|
<h3 style="font-size: 12px; margin-top: 20px"> |
||||
|
Server time: {{ .servertime }} | <a href="/txpool">Transaction pool</a> |
||||
|
</h3> |
||||
|
|
||||
|
|
||||
|
<h3 style="font-size: 12px; margin-top: 5px; margin-bottom: 3"> |
||||
|
Network difficulty: {{ .Network_Difficulty }} |
||||
|
| Hash rate: {{ .hash_rate }} MH/s |
||||
|
| Mempool size : {{ .txpool_size }} |
||||
|
<!-- | Fee per kb: 0.001198930000 |
||||
|
| Median block size limit: 292.97 kB |
||||
|
--> |
||||
|
</h3> |
||||
|
|
||||
|
</div> |
||||
|
{{end}} |
||||
|
{{end}} |
||||
|
` |
||||
|
|
||||
|
var block_template string = `{{define "block"}} |
||||
|
{{ template "header" . }} |
||||
|
<div> |
||||
|
<H4>Block hash (height): {{.block.Hash}} ({{.block.Height}})</H4> |
||||
|
<H5>Previous block: <a href="/block/{{.block.Prev_Hash}}">{{.block.Prev_Hash}}</a></H5> |
||||
|
<!-- |
||||
|
<H5>Next block: <a href="/block/a8ade20d5cad5e23105cfc25687beb2498844a984b1450330c67705b6c720596">a8ade20d5cad5e23105cfc25687beb2498844a984b1450330c67705b6c720596</a></H5> |
||||
|
--> |
||||
|
<table class="center"> |
||||
|
<tr> |
||||
|
<td>Timestamp [UCT] (epoch):</td><td>{{.block.Block_time}} ({{.block.Epoch}})</td> |
||||
|
<td>Age [h:m:s]:</td><td>{{.block.Age}}</td> |
||||
|
<td>Δ [h:m:s]:</td><td></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>Major.minor version:</td><td>{{.block.Major_Version}}.{{.block.Minor_Version}}</td> |
||||
|
<td>Block reward:</td><td>{{.block.Reward}}</td> |
||||
|
<td>Block size [kB]:</td><td>{{.block.Size}}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>nonce:</td><td>{{.block.Nonce}}</td> |
||||
|
<td>Total fees:</td><td>{{.block.Fees}}</td> |
||||
|
<td>No of txs:</td><td>{{.block.Tx_Count}}</td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
|
||||
|
<h3>Miner reward transaction</h3> |
||||
|
<table class="center"> |
||||
|
<tr> |
||||
|
<td>hash</td> |
||||
|
<td>outputs</td> |
||||
|
<td>size [kB]</td> |
||||
|
<td>version</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td><a href="/tx/{{.block.Mtx.Hash}}">{{.block.Mtx.Hash}}</a> |
||||
|
<td>{{.block.Mtx.Amount}}</td> |
||||
|
<td>{{.block.Mtx.Size}}</td> |
||||
|
<td>{{.block.Mtx.Version}}</td> |
||||
|
</tr> |
||||
|
|
||||
|
</table> |
||||
|
|
||||
|
<h3>Transactions ({{.block.Tx_Count}})</h3> |
||||
|
<table class="center" style="width:80%"> |
||||
|
<tr> |
||||
|
<td>hash</td> |
||||
|
<td>outputs</td> |
||||
|
<td>fee</td> |
||||
|
<td>ring size</td> |
||||
|
<td>in/out</td> |
||||
|
|
||||
|
<td>version</td> |
||||
|
<td>size [kB]</td> |
||||
|
</tr> |
||||
|
{{range .block.Txs}} |
||||
|
<tr> |
||||
|
<td><a href="/tx/{{.Hash}}">{{.Hash}}</a></td> |
||||
|
<td>?</td> |
||||
|
<td>{{.Fee}}</td> |
||||
|
<td>{{.Ring_size}}</td> |
||||
|
<td>{{.In}}/{{.Out}}</td> |
||||
|
<td>{{.Version}}</td> |
||||
|
<td>{{.Size}}</td> |
||||
|
</tr> |
||||
|
{{end}} |
||||
|
</table> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
{{ template "footer" . }} |
||||
|
{{end}} |
||||
|
` |
||||
|
|
||||
|
var tx_template string = `{{define "tx"}} |
||||
|
{{ template "header" . }} |
||||
|
<div> |
||||
|
<H4 style="margin:5px">Tx hash: {{.info.Hash}}</H4> |
||||
|
<H5 style="margin:5px">Tx prefix hash: {{.info.PrefixHash}}</H5> |
||||
|
<H5 style="margin:5px">Tx public key: TODO</H5> |
||||
|
|
||||
|
<table class="center" style="width: 80%; margin-top:10px"> |
||||
|
<tr> |
||||
|
<td>Timestamp: {{.info.Timestamp}} </td> |
||||
|
<td>Timestamp [UCT]: {{.info.Block_time}}</td> |
||||
|
<td>Age [y:d:h:m:s]: {{.info.Age}} </td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>Block: <a href="/block/{{.info.Height}}">{{.info.Height}}</a></td> |
||||
|
<td>Fee: {{.info.Fee}}</td> |
||||
|
<td>Tx size: {{.info.Size}} kB</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>Tx version: {{.info.Version}}</td> |
||||
|
<td>No of confirmations: {{.info.Depth}}</td> |
||||
|
<td>Signature type: {{.info.Type}}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td colspan="3">Extra: {{.info.Extra}}</td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
<h3>{{.info.Out}} output(s) for total of {{.info.Amount}} dero</h3> |
||||
|
<div class="center"> |
||||
|
<table class="center"> |
||||
|
<tr> |
||||
|
<td>stealth address</td> |
||||
|
<td>amount</td> |
||||
|
<td>amount idx</td> |
||||
|
</tr> |
||||
|
|
||||
|
{{range $i, $e := .info.OutAddress}} |
||||
|
<tr> |
||||
|
<td>{{ $e }}</td> |
||||
|
<td>{{$.info.Amount}}</td> |
||||
|
<td>{{index $.info.OutOffset $i}}</td> |
||||
|
</tr> |
||||
|
{{end}} |
||||
|
</table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- TODO currently we donot enable user to prove or decode something --> |
||||
|
|
||||
|
{{if eq .info.CoinBase false}} |
||||
|
|
||||
|
<h3>{{.info.In}} input(s) for total of ? dero</h3> |
||||
|
<div class="center"> |
||||
|
<table class="center"> |
||||
|
{{range .info.Keyimages}} |
||||
|
<tr> |
||||
|
<td style="text-align: center;"> |
||||
|
key image {{ . }} |
||||
|
</td> |
||||
|
<td>amount: ?</td> |
||||
|
</tr> |
||||
|
{{end}} |
||||
|
</table> |
||||
|
</div> |
||||
|
{{end}} |
||||
|
</div> |
||||
|
{{ template "footer" . }} |
||||
|
|
||||
|
{{end}}` |
||||
|
|
||||
|
var txpool_template string = `{{define "txpool"}} |
||||
|
<h2 style="margin-bottom: 0px"> |
||||
|
Transaction pool |
||||
|
</h2> |
||||
|
<h4 style="font-size: 12px; margin-top: 0px">(no of txs: {{ .txpool_size }}, size: 0.00 kB, updated every 5 seconds)</h4> |
||||
|
<div class="center"> |
||||
|
|
||||
|
<table class="center" style="width:80%"> |
||||
|
<tr> |
||||
|
<td>age [h:m:s]</td> |
||||
|
<td>transaction hash</td> |
||||
|
<td>fee</td> |
||||
|
<td>outputs</td> |
||||
|
<td>in(nonrct)/out</td> |
||||
|
<td>ring size</td> |
||||
|
<td>tx size [kB]</td> |
||||
|
</tr> |
||||
|
|
||||
|
|
||||
|
{{range .mempool}} |
||||
|
<tr> |
||||
|
<td></td> |
||||
|
<td><a href="/tx/{{.Hash}}">{{.Hash}}</a></td> |
||||
|
<td>{{.Fee}}</td> |
||||
|
<td>N/A</td> |
||||
|
<td>{{.In}}/{{.Out}}</td> |
||||
|
<td>{{.Ring_size}}</td> |
||||
|
<td>{{.Size}}</td> |
||||
|
|
||||
|
</tr> |
||||
|
|
||||
|
{{end}} |
||||
|
</table> |
||||
|
|
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
{{end}}` |
||||
|
|
||||
|
// full page txpool_template
|
||||
|
var txpool_page_template string = `{{define "txpool_page"}} |
||||
|
{{ template "header" . }} |
||||
|
{{ template "txpool" . }} |
||||
|
{{ template "footer" . }} |
||||
|
{{end}}` |
||||
|
|
||||
|
var main_template string = ` |
||||
|
{{define "main"}} |
||||
|
{{ template "header" . }} |
||||
|
{{ template "txpool" . }} |
||||
|
|
||||
|
<h2 style="margin-bottom: 0px">Transactions in the last 11 blocks</h2> |
||||
|
|
||||
|
<h4 style="font-size: 14px; margin-top: 0px">(Median size of these blocks: 0.09 kB)</h4> |
||||
|
|
||||
|
<div class="center"> |
||||
|
|
||||
|
<table class="center"> |
||||
|
<tr> |
||||
|
<td>height</td> |
||||
|
<td>age [h:m:s]<!--(Δm)--></td> |
||||
|
<td>size [kB]<!--(Δm)--></td> |
||||
|
<td>tx hash</td> |
||||
|
<td>fees</td> |
||||
|
<td>outputs</td> |
||||
|
<td>in(nonrct)/out</td> |
||||
|
<td>ring size</td> |
||||
|
<td>tx size [kB]</td> |
||||
|
</tr> |
||||
|
|
||||
|
|
||||
|
{{range .block_array}} |
||||
|
<tr> |
||||
|
<td><a href="/block/{{.Height}}">{{.Height}}</a></td> |
||||
|
<td>{{.Age}}</td> |
||||
|
<td>{{.Size}}</td> |
||||
|
<td><a href="/tx/{{.Mtx.Hash}}">{{.Mtx.Hash}}</a></td> |
||||
|
<td>N/A</td> |
||||
|
<td>{{.Mtx.Amount}}</td> |
||||
|
<td>{{.Mtx.In}}/{{.Mtx.Out}}</td> |
||||
|
<td>0</td> |
||||
|
<td>{{.Mtx.Size}}</td> |
||||
|
|
||||
|
</tr> |
||||
|
|
||||
|
{{range .Txs}} |
||||
|
<tr> |
||||
|
<td></td> |
||||
|
<td></td> |
||||
|
<td></td> |
||||
|
<td><a href="/tx/{{.Hash}}">{{.Hash}}</a></td> |
||||
|
<td>{{.Fee}}</td> |
||||
|
<td>N/A</td> |
||||
|
<td>{{.In}}/{{.Out}}</td> |
||||
|
<td>{{.Ring_size}}</td> |
||||
|
<td>{{.Size}}</td> |
||||
|
|
||||
|
</tr> |
||||
|
{{end}} |
||||
|
|
||||
|
{{end}} |
||||
|
</table> |
||||
|
{{ template "paging" . }} |
||||
|
|
||||
|
</div> |
||||
|
{{ template "footer" . }} |
||||
|
{{end}}` |
||||
|
|
||||
|
var paging_template string = `{{ define "paging"}} |
||||
|
|
||||
|
<div id="pages" class="center" style="text-align: center;"> |
||||
|
<a href="/page/{{.previous_page}}">previous page</a> | |
||||
|
<a href="/">first page</a> | |
||||
|
current page: {{.current_page}}/<a href="/page/{{.total_page}}">{{.total_page}}</a> |
||||
|
| <a href="/page/{{.next_page}}">next page</a> |
||||
|
</div> |
||||
|
|
||||
|
{{end}}` |
||||
|
|
||||
|
var footer_template string = ` {{define "footer"}} |
||||
|
<div class="center"> |
||||
|
<h6 style="margin-top:10px"> |
||||
|
<a href="https://github.com/deroproject/">DERO explorer source code</a> |
||||
|
| explorer version (api): under development (1.0) |
||||
|
| dero version: golang pre-alpha |
||||
|
| Copyright 2017-2018 Dero Project |
||||
|
</h6> |
||||
|
</div> |
||||
|
</body> |
||||
|
</html> |
||||
|
{{end}} |
||||
|
` |
@ -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. |
||||
|
|
@ -1,8 +1,12 @@ |
|||||
|
// 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
|
||||
|
|
||||
package config |
package config |
||||
|
|
||||
import "testing" |
import "testing" |
||||
|
|
||||
|
func Test_Part1(t *testing.T) { |
||||
|
|
||||
func Test_Part1(t *testing.T){ |
|
||||
|
|
||||
} |
} |
@ -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,196 @@ |
|||||
|
// 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 crypto |
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "testing" |
||||
|
import "bufio" |
||||
|
import "log" |
||||
|
import "os" |
||||
|
import "strings" |
||||
|
import "strconv" |
||||
|
import "encoding/hex" |
||||
|
|
||||
|
// these tests, specifically "tests_data.txt" are available in the monero project and used here to verify whether we implement everything
|
||||
|
|
||||
|
func Test_Crypto(t *testing.T) { |
||||
|
|
||||
|
file, err := os.Open("tests_data.txt") |
||||
|
if err != nil { |
||||
|
log.Fatalf("Test file tests_data is missing, err %s ", err) |
||||
|
} |
||||
|
defer file.Close() |
||||
|
|
||||
|
scanner := bufio.NewScanner(file) |
||||
|
for scanner.Scan() { |
||||
|
// parse the line
|
||||
|
line := scanner.Text() |
||||
|
words := strings.Fields(line) |
||||
|
|
||||
|
if len(words) < 2 { |
||||
|
continue |
||||
|
} |
||||
|
switch words[0] { |
||||
|
case "check_scalar": |
||||
|
scalar := HexToKey(words[1]) |
||||
|
expected := "true" == words[2] |
||||
|
actual := ScValid(&scalar) == true |
||||
|
if actual != expected { |
||||
|
t.Fatalf("Failed %s: Expected %v, got %v.", words[0], expected, actual) |
||||
|
} |
||||
|
case "check_key": |
||||
|
public_key := HexToKey(words[1]) |
||||
|
expected := "true" == words[2] |
||||
|
actual := public_key.Public_Key_Valid() == true |
||||
|
if actual != expected { |
||||
|
t.Logf("Failed %s: Expected %v, got %v %s", words[0], expected, actual, public_key) |
||||
|
} |
||||
|
|
||||
|
case "random_scalar": // ignore them
|
||||
|
case "hash_to_scalar": |
||||
|
data, _ := hex.DecodeString(words[1]) |
||||
|
expected := HexToKey(words[2]) |
||||
|
actual := HashToScalar(data) |
||||
|
if *actual != expected { |
||||
|
t.Fatalf("Failed %s: Expected %v, got %v.", words[0], expected, actual) |
||||
|
} |
||||
|
//t.Logf("executing %s\n", expected)
|
||||
|
case "generate_keys": // this test is meant to test RNG ??
|
||||
|
key_secret := HexToKey(words[2]) |
||||
|
key_public := HexToKey(words[1]) |
||||
|
|
||||
|
if key_public != *(key_secret.PublicKey()) { |
||||
|
t.Errorf("Failed %s key generation testing failed %s ", words[0], key_secret) |
||||
|
} |
||||
|
case "secret_key_to_public_key": |
||||
|
key_secret := HexToKey(words[1]) |
||||
|
|
||||
|
expected := "true" == words[2] |
||||
|
actual := key_secret.Private_Key_Valid() |
||||
|
|
||||
|
if expected != actual { |
||||
|
t.Fatalf("Failed %s: Expected %v, got %v. %s", words[0], expected, actual, key_secret) |
||||
|
} |
||||
|
|
||||
|
if actual { // test only if required
|
||||
|
key_public := HexToKey(words[3]) |
||||
|
if key_public != *(key_secret.PublicKey()) { |
||||
|
t.Errorf("Failed %s key generation testing failed %s ", words[0], key_secret) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
case "generate_key_derivation": |
||||
|
public_key := HexToKey(words[1]) |
||||
|
private_key := HexToKey(words[2]) |
||||
|
|
||||
|
expected := "true" == words[3] |
||||
|
actual := public_key.Public_Key_Valid() |
||||
|
|
||||
|
if expected != actual { |
||||
|
t.Fatalf(" Failed %s: Expected %v, got %v. %s", words[0], expected, actual, public_key) |
||||
|
} |
||||
|
|
||||
|
if expected == true { // yes knowingly using the same variables
|
||||
|
expected := HexToKey(words[4]) |
||||
|
actual := KeyDerivation(&public_key, &private_key) |
||||
|
|
||||
|
if expected != actual { |
||||
|
t.Fatalf("Failed %s: Expected %v, got %v. %s", words[0], expected, actual, public_key) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
case "derive_public_key": |
||||
|
kd := HexToKey(words[1]) //
|
||||
|
outIdx, _ := strconv.ParseUint(words[2], 10, 0) |
||||
|
base := HexToKey(words[3]) |
||||
|
var expected1, actual1 bool |
||||
|
var expected2, actual2 Key |
||||
|
expected1 = words[4] == "true" |
||||
|
if expected1 { |
||||
|
expected2 = HexToKey(words[5]) |
||||
|
} |
||||
|
|
||||
|
actual1 = base.Public_Key_Valid() |
||||
|
if actual1 != expected1 { |
||||
|
t.Fatalf("%s: Expected %v, got %v.", words[0], expected1, actual1) |
||||
|
} |
||||
|
|
||||
|
if expected1 { |
||||
|
actual2 = kd.KeyDerivation_To_PublicKey(outIdx, base) |
||||
|
if actual2 != expected2 { |
||||
|
t.Fatalf("%s: Expected %v, got %v.", words[0], expected2, actual2) |
||||
|
} |
||||
|
} |
||||
|
case "derive_secret_key": |
||||
|
kd := HexToKey(words[1]) //
|
||||
|
outIdx, _ := strconv.ParseUint(words[2], 10, 0) |
||||
|
base := HexToKey(words[3]) |
||||
|
expected := HexToKey(words[4]) |
||||
|
|
||||
|
actual := kd.KeyDerivation_To_PrivateKey(outIdx, base) |
||||
|
if actual != expected { |
||||
|
t.Fatalf("%s: Expected %v, got %v.", words[0], expected, actual) |
||||
|
} |
||||
|
|
||||
|
case "hash_to_point": // this is different check than HashToPoint
|
||||
|
hash := HexToKey(words[1]) |
||||
|
expected := HexToKey(words[2]) |
||||
|
|
||||
|
var actual Key |
||||
|
var p1 ProjectiveGroupElement |
||||
|
p1.FromBytes(&hash) |
||||
|
p1.ToBytes(&actual) |
||||
|
|
||||
|
if actual != expected { |
||||
|
t.Logf("%s: Expected %v, got %v.", words[0], expected, actual) |
||||
|
} |
||||
|
case "hash_to_ec": |
||||
|
pub := HexToKey(words[1]) |
||||
|
expected := HexToKey(words[2]) |
||||
|
|
||||
|
var actual Key |
||||
|
ex := pub.HashToEC() |
||||
|
ex.ToBytes(&actual) |
||||
|
|
||||
|
if actual != expected { |
||||
|
t.Fatalf("%s: Expected %s, got %s.", words[0], expected, actual) |
||||
|
} |
||||
|
|
||||
|
case "generate_key_image": |
||||
|
public_key := HexToKey(words[1]) |
||||
|
private_key := HexToKey(words[2]) |
||||
|
expected := HexToKey(words[3]) |
||||
|
|
||||
|
actual := GenerateKeyImage(public_key, private_key) |
||||
|
if actual != expected { |
||||
|
t.Fatalf("%s: Expected %s, got %s.", words[0], expected, actual) |
||||
|
} |
||||
|
|
||||
|
// these are ignored because they are not required DERO project is based on ringct+
|
||||
|
case "generate_signature": |
||||
|
case "check_signature": |
||||
|
case "generate_ring_signature": |
||||
|
case "check_ring_signature": |
||||
|
|
||||
|
default: |
||||
|
|
||||
|
t.Fatalf("This test is not handled %s: ", words[0]) |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -1,13 +1,404 @@ |
|||||
|
// 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 crypto |
package crypto |
||||
|
|
||||
|
import "io" |
||||
import "fmt" |
import "fmt" |
||||
|
import "bytes" |
||||
|
import "crypto/rand" |
||||
|
import "encoding/hex" |
||||
|
import "encoding/binary" |
||||
|
|
||||
const KeyLength = 32 |
const KeyLength = 32 |
||||
|
|
||||
|
|
||||
// Key can be a Scalar or a Point
|
// Key can be a Scalar or a Point
|
||||
type Key [KeyLength]byte |
type Key [KeyLength]byte |
||||
|
|
||||
func (k Key) MarshalText() ([]byte, error) { |
func (k Key) MarshalText() ([]byte, error) { |
||||
return []byte(fmt.Sprintf("%x", k[:])), nil |
return []byte(fmt.Sprintf("%x", k[:])), nil |
||||
} |
} |
||||
|
|
||||
|
func (k Key) String() string { |
||||
|
return fmt.Sprintf("%x", k[:]) |
||||
|
} |
||||
|
|
||||
|
func (p *Key) FromBytes(b [KeyLength]byte) { |
||||
|
*p = b |
||||
|
} |
||||
|
|
||||
|
func (p *Key) ToBytes() (result [KeyLength]byte) { |
||||
|
result = [KeyLength]byte(*p) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// convert a hex string to a key
|
||||
|
func HexToKey(h string) (result Key) { |
||||
|
byteSlice, _ := hex.DecodeString(h) |
||||
|
if len(byteSlice) != 32 { |
||||
|
panic("Incorrect key size") |
||||
|
} |
||||
|
copy(result[:], byteSlice) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
func HexToHash(h string) (result Hash) { |
||||
|
byteSlice, _ := hex.DecodeString(h) |
||||
|
if len(byteSlice) != 32 { |
||||
|
panic("Incorrect key size") |
||||
|
} |
||||
|
copy(result[:], byteSlice) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// generates a public from the secret key
|
||||
|
func (p *Key) PublicKey() (pubKey *Key) { |
||||
|
point := new(ExtendedGroupElement) |
||||
|
GeScalarMultBase(point, p) |
||||
|
pubKey = new(Key) |
||||
|
point.ToBytes(pubKey) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// tests whether the key is valid ( represents a point on the curve )
|
||||
|
func (k *Key) Public_Key_Valid() bool { |
||||
|
var point ExtendedGroupElement |
||||
|
return point.FromBytes(k) |
||||
|
} |
||||
|
|
||||
|
func (k *Key) Private_Key_Valid() bool { |
||||
|
return Sc_check(k) |
||||
|
} |
||||
|
|
||||
|
// Creates a point on the Edwards Curve by hashing the key
|
||||
|
func (p *Key) HashToEC() (result *ExtendedGroupElement) { |
||||
|
result = new(ExtendedGroupElement) |
||||
|
var p1 ProjectiveGroupElement |
||||
|
var p2 CompletedGroupElement |
||||
|
h := Key(Keccak256(p[:])) |
||||
|
p1.FromBytes(&h) |
||||
|
GeMul8(&p2, &p1) |
||||
|
p2.ToExtended(result) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
func (p *Key) HashToPoint() (result Key) { |
||||
|
extended := p.HashToEC() |
||||
|
extended.ToBytes(&result) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// this uses random number generator from the OS
|
||||
|
func RandomScalar() (result *Key) { |
||||
|
result = new(Key) |
||||
|
var reduceFrom [KeyLength * 2]byte |
||||
|
tmp := make([]byte, KeyLength*2) |
||||
|
rand.Read(tmp) |
||||
|
copy(reduceFrom[:], tmp) |
||||
|
ScReduce(result, &reduceFrom) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// generate a new private-public key pair
|
||||
|
func NewKeyPair() (privKey *Key, pubKey *Key) { |
||||
|
privKey = RandomScalar() |
||||
|
pubKey = privKey.PublicKey() |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
func ParseKey(buf io.Reader) (result Key, err error) { |
||||
|
key := make([]byte, KeyLength) |
||||
|
if _, err = buf.Read(key); err != nil { |
||||
|
return |
||||
|
} |
||||
|
copy(result[:], key) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
//does a * G where a is a scalar and G is the curve basepoint
|
||||
|
key scalarmultBase(const key & a) { |
||||
|
ge_p3 point; |
||||
|
key aG; |
||||
|
sc_reduce32copy(aG.bytes, a.bytes); //do this beforehand
|
||||
|
ge_scalarmult_base(&point, aG.bytes); |
||||
|
ge_p3_tobytes(aG.bytes, &point); |
||||
|
return aG; |
||||
|
} |
||||
|
*/ |
||||
|
//does a * G where a is a scalar and G is the curve basepoint
|
||||
|
|
||||
|
func ScalarmultBase(a Key) (aG Key) { |
||||
|
reduce32copy := a |
||||
|
ScReduce32(&reduce32copy) |
||||
|
point := new(ExtendedGroupElement) |
||||
|
GeScalarMultBase(point, &a) |
||||
|
point.ToBytes(&aG) |
||||
|
return aG |
||||
|
} |
||||
|
|
||||
|
// generates a key which can be used as private key or mask
|
||||
|
// this function is similiar to RandomScalar except for reduce32, TODO can we merge both
|
||||
|
func skGen() Key { |
||||
|
skey := RandomScalar() |
||||
|
ScReduce32(skey) |
||||
|
return *skey |
||||
|
} |
||||
|
|
||||
|
func (k *Key) ToExtended() (result *ExtendedGroupElement) { |
||||
|
result = new(ExtendedGroupElement) |
||||
|
result.FromBytes(k) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// bothe the function resturn identity of the ed25519 curve
|
||||
|
func identity() (result *Key) { |
||||
|
result = new(Key) |
||||
|
result[0] = 1 |
||||
|
return |
||||
|
} |
||||
|
func CurveIdentity() (result Key) { |
||||
|
result = Identity |
||||
|
return result |
||||
|
} |
||||
|
|
||||
|
func CurveOrder() (result Key) { |
||||
|
result = L |
||||
|
return result |
||||
|
} |
||||
|
|
||||
|
// convert a uint64 to a scalar
|
||||
|
func d2h(val uint64) (result *Key) { |
||||
|
result = new(Key) |
||||
|
for i := 0; val > 0; i++ { |
||||
|
result[i] = byte(val & 0xFF) |
||||
|
val /= 256 |
||||
|
} |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
func HashToScalar(data ...[]byte) (result *Key) { |
||||
|
result = new(Key) |
||||
|
*result = Key(Keccak256(data...)) |
||||
|
ScReduce32(result) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// does a * P where a is a scalar and P is an arbitrary point
|
||||
|
func ScalarMultKey(Point *Key, scalar *Key) (result *Key) { |
||||
|
P := new(ExtendedGroupElement) |
||||
|
P.FromBytes(Point) |
||||
|
resultPoint := new(ProjectiveGroupElement) |
||||
|
GeScalarMult(resultPoint, scalar, P) |
||||
|
result = new(Key) |
||||
|
resultPoint.ToBytes(result) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// multiply a scalar by H (second curve point of Pedersen Commitment)
|
||||
|
func ScalarMultH(scalar *Key) (result *Key) { |
||||
|
h := new(ExtendedGroupElement) |
||||
|
h.FromBytes(&H) |
||||
|
resultPoint := new(ProjectiveGroupElement) |
||||
|
GeScalarMult(resultPoint, scalar, h) |
||||
|
result = new(Key) |
||||
|
resultPoint.ToBytes(result) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// add two points together
|
||||
|
func AddKeys(sum, k1, k2 *Key) { |
||||
|
a := k1.ToExtended() |
||||
|
b := new(CachedGroupElement) |
||||
|
k2.ToExtended().ToCached(b) |
||||
|
c := new(CompletedGroupElement) |
||||
|
geAdd(c, a, b) |
||||
|
tmp := new(ExtendedGroupElement) |
||||
|
c.ToExtended(tmp) |
||||
|
tmp.ToBytes(sum) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// compute a*G + b*B
|
||||
|
func AddKeys2(result, a, b, B *Key) { |
||||
|
BPoint := B.ToExtended() |
||||
|
RPoint := new(ProjectiveGroupElement) |
||||
|
GeDoubleScalarMultVartime(RPoint, b, BPoint, a) |
||||
|
RPoint.ToBytes(result) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
//addKeys3
|
||||
|
//aAbB = a*A + b*B where a, b are scalars, A, B are curve points
|
||||
|
//B must be input after applying "precomp"
|
||||
|
func AddKeys3(result *Key, a *Key, A *Key, b *Key, B_Precomputed *[8]CachedGroupElement) { |
||||
|
A_Point := new(ExtendedGroupElement) |
||||
|
A_Point.FromBytes(A) |
||||
|
|
||||
|
result_projective := new(ProjectiveGroupElement) |
||||
|
GeDoubleScalarMultPrecompVartime(result_projective, a, A_Point, b, B_Precomputed) |
||||
|
result_projective.ToBytes(result) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// subtract two points A - B
|
||||
|
func SubKeys(diff, k1, k2 *Key) { |
||||
|
a := k1.ToExtended() |
||||
|
b := new(CachedGroupElement) |
||||
|
k2.ToExtended().ToCached(b) |
||||
|
c := new(CompletedGroupElement) |
||||
|
geSub(c, a, b) |
||||
|
tmp := new(ExtendedGroupElement) |
||||
|
c.ToExtended(tmp) |
||||
|
tmp.ToBytes(diff) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// this gives you a commitment from an amount
|
||||
|
// this is used to convert tx fee or miner tx amount to commitment
|
||||
|
func Commitment_From_Amount(amount uint64) Key { |
||||
|
return *(ScalarMultH(d2h(amount))) |
||||
|
} |
||||
|
|
||||
|
// this is used to convert miner tx commitment to mask
|
||||
|
// equivalent to rctOps.cpp zeroCommit
|
||||
|
func ZeroCommitment_From_Amount(amount uint64) Key { |
||||
|
mask := *(identity()) |
||||
|
mask = ScalarmultBase(mask) |
||||
|
am := d2h(amount) |
||||
|
bH := ScalarMultH(am) |
||||
|
AddKeys(&mask, &mask, bH) |
||||
|
return mask |
||||
|
} |
||||
|
|
||||
|
// zero fill the key
|
||||
|
func Sc_0(k *Key) { |
||||
|
for i := 0; i < 32; i++ { |
||||
|
k[i] = 0 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// RandomPubKey takes a random scalar, interprets it as a point on the curve
|
||||
|
// remember the low order bug and do more auditing of the entire thing
|
||||
|
func RandomPubKey() (result *Key) { |
||||
|
result = new(Key) |
||||
|
p3 := new(ExtendedGroupElement) |
||||
|
var p1 ProjectiveGroupElement |
||||
|
var p2 CompletedGroupElement |
||||
|
h := RandomScalar() |
||||
|
p1.FromBytes(h) |
||||
|
GeMul8(&p2, &p1) |
||||
|
p2.ToExtended(p3) |
||||
|
p3.ToBytes(result) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// this is the main key derivation function and is the crux
|
||||
|
// when deriving keys in the case user A wants to send DERO to another user B ( this is outgoing case)
|
||||
|
// public key is B's view key
|
||||
|
// private keys is TX private key
|
||||
|
// if user B wants to derive key, he needs to ( this is incoming case )
|
||||
|
// public key is TX public key
|
||||
|
// private is B's private keys
|
||||
|
// HOPE the above is clean and clear
|
||||
|
|
||||
|
func KeyDerivation(pub *Key, priv *Key) (KeyDerivation Key) { |
||||
|
var point ExtendedGroupElement |
||||
|
var point2 ProjectiveGroupElement |
||||
|
var point3 CompletedGroupElement |
||||
|
|
||||
|
if !priv.Private_Key_Valid() { |
||||
|
panic("Invalid private key.") |
||||
|
} |
||||
|
tmp := *pub |
||||
|
if !point.FromBytes(&tmp) { |
||||
|
panic("Invalid public key.") |
||||
|
} |
||||
|
|
||||
|
tmp = *priv |
||||
|
GeScalarMult(&point2, &tmp, &point) |
||||
|
GeMul8(&point3, &point2) |
||||
|
point3.ToProjective(&point2) |
||||
|
|
||||
|
point2.ToBytes(&tmp) |
||||
|
return tmp |
||||
|
} |
||||
|
|
||||
|
// the origincal c implementation needs to be checked for varint overflow
|
||||
|
// we also need to check the compatibility of golang varint with cryptonote implemented varint
|
||||
|
// outputIndex is the position of output within that specific transaction
|
||||
|
func (k *Key) KeyDerivationToScalar(outputIndex uint64) (scalar *Key) { |
||||
|
tmp := make([]byte, 12, 12) |
||||
|
|
||||
|
length := binary.PutUvarint(tmp, outputIndex) |
||||
|
tmp = tmp[:length] |
||||
|
|
||||
|
var buf bytes.Buffer |
||||
|
buf.Write(k[:]) |
||||
|
buf.Write(tmp) |
||||
|
scalar = HashToScalar(buf.Bytes()) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// generate ephermal keys from a key derivation
|
||||
|
// base key is the B's public spend key or A's private spend key
|
||||
|
// outputIndex is the position of output within that specific transaction
|
||||
|
func (kd *Key) KeyDerivation_To_PublicKey(outputIndex uint64, baseKey Key) Key { |
||||
|
|
||||
|
var point1, point2 ExtendedGroupElement |
||||
|
var point3 CachedGroupElement |
||||
|
var point4 CompletedGroupElement |
||||
|
var point5 ProjectiveGroupElement |
||||
|
|
||||
|
tmp := baseKey |
||||
|
if !point1.FromBytes(&tmp) { |
||||
|
panic("Invalid public key.") |
||||
|
} |
||||
|
scalar := kd.KeyDerivationToScalar(outputIndex) |
||||
|
GeScalarMultBase(&point2, scalar) |
||||
|
point2.ToCached(&point3) |
||||
|
geAdd(&point4, &point1, &point3) |
||||
|
point4.ToProjective(&point5) |
||||
|
point5.ToBytes(&tmp) |
||||
|
return tmp |
||||
|
} |
||||
|
|
||||
|
// generate ephermal keys from a key derivation
|
||||
|
// base key is the A's private spend key
|
||||
|
// outputIndex is the position of output within that specific transaction
|
||||
|
func (kd *Key) KeyDerivation_To_PrivateKey(outputIndex uint64, baseKey Key) Key { |
||||
|
if !baseKey.Private_Key_Valid() { |
||||
|
panic("Invalid private key.") |
||||
|
} |
||||
|
scalar := kd.KeyDerivationToScalar(outputIndex) |
||||
|
|
||||
|
tmp := baseKey |
||||
|
ScAdd(&tmp, &tmp, scalar) |
||||
|
return tmp |
||||
|
} |
||||
|
|
||||
|
// NewKeyImage creates a new KeyImage from the given public and private keys.
|
||||
|
// The keys are usually the ephemeral keys derived using KeyDerivation.
|
||||
|
func GenerateKeyImage(pub Key, private Key) Key { |
||||
|
var proj ProjectiveGroupElement |
||||
|
|
||||
|
ext := pub.HashToEC() |
||||
|
GeScalarMult(&proj, &private, ext) |
||||
|
|
||||
|
var ki Key |
||||
|
proj.ToBytes(&ki) |
||||
|
return ki |
||||
|
} |
@ -0,0 +1,163 @@ |
|||||
|
// 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 crypto |
||||
|
|
||||
|
//import "fmt"
|
||||
|
import "testing" |
||||
|
|
||||
|
// these test were orignally written for mnemonics, but they can be used here also
|
||||
|
|
||||
|
func Test_Public_Private_Key(t *testing.T) { |
||||
|
|
||||
|
tests := []struct { |
||||
|
name string |
||||
|
seed string |
||||
|
spend_key_secret string |
||||
|
spend_key_public string |
||||
|
view_key_secret string |
||||
|
view_key_public string |
||||
|
Address string |
||||
|
}{ |
||||
|
{ |
||||
|
name: "English", |
||||
|
seed: "sequence atlas unveil summon pebbles tuesday beer rudely snake rockets different fuselage woven tagged bested dented vegan hover rapid fawns obvious muppet randomly seasons randomly", |
||||
|
spend_key_secret: "b0ef6bd527b9b23b9ceef70dc8b4cd1ee83ca14541964e764ad23f5151204f0f", |
||||
|
spend_key_public: "7d996b0f2db6dbb5f2a086211f2399a4a7479b2c911af307fdc3f7f61a88cb0e", |
||||
|
view_key_secret: "42ba20adb337e5eca797565be11c9adb0a8bef8c830bccc2df712535d3b8f608", |
||||
|
view_key_public: "1c06bcac7082f73af10460b5f2849aded79374b2fbdaae5d9384b9b6514fddcb", |
||||
|
Address: "dETocsF4EuzXaxLNbDLLWi6xNEzzBJ2He5WSf7He8peuPt4nTyakAFyNuXqrHAGQt1PBSBonCRRj8daUtF7TPXFW42YQkxUQzg", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "Deutsch", |
||||
|
seed: "Dekade Spagat Bereich Radclub Yeti Dialekt Unimog Nomade Anlage Hirte Besitz Märzluft Krabbe Nabel Halsader Chefarzt Hering tauchen Neuerung Reifen Umgang Hürde Alchimie Amnesie Reifen", |
||||
|
spend_key_secret: "a00b3c431e0037426f12b255aaca918863c8bbc690ff3765564bcc1de7fbb303", |
||||
|
spend_key_public: "6f6d202f715d23ff4034a42298fd7b36431dbbfe8559df642911a9c3143ab802", |
||||
|
view_key_secret: "eb2e288ac34e8d4f51cf73b8fda5240c2f3a25f72f4e7b4ac33f33fdc6602300", |
||||
|
view_key_public: "ec9769a6fc9a10a474ba27bb62a58cb55e51aca4107b3daa613c054e4a104d75", |
||||
|
Address: "dETobGVx1rYGaagDmPbfGjjQ5zeVkHXDeG2ssGnyrWgbApeTgRHhPJBSmdAj76XJFKUh3FtNv7fjMMcbGsLnms8V1cqG9Euc5i", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "Español", |
||||
|
seed: "perfil lujo faja puma favor pedir detalle doble carbón neón paella cuarto ánimo cuento conga correr dental moneda león donar entero logro realidad acceso doble", |
||||
|
spend_key_secret: "4f1101c4cc6adc6e6a63acde4e71fd76dc4471fa54769866d5e80a0a3d53d00c", |
||||
|
spend_key_public: "7f28c0b9c5e59fb57a6c4171f6b19faa369bd50c53b792fcdf2402369ded26a7", |
||||
|
view_key_secret: "2de547b9fa3be9db08871d3964027a8f0d8d9c36755257841ba838cfff9fd60a", |
||||
|
view_key_public: "caf4787a2eb8aa94e11a5a7ac912daa820a8148ea175b03a13d4322adab0c33f", |
||||
|
Address: "dETod3T65GgfQe4xkLfu2mWiAzdR6ZRPgXhuAdJqKRUpgffP7dP3C5BXtVhPTwLJZE49uhjBDBkLxLgj3835HxiM7hWoS7trc1", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "Français", |
||||
|
seed: "lisser onctueux pierre trace flair riche machine ordre soir nougat talon balle biceps crier trame tenu gorge cuisine taverne presque laque argent roche secte ordre", |
||||
|
spend_key_secret: "340ed50ef73ba172e2fef23dc9f60e314f609bb7692d22d59f3938c391570b0a", |
||||
|
spend_key_public: "1b2e329fb7fbf1e3d93a30d66e72f13e19addc49ece84839bf2772d685b1bf20", |
||||
|
view_key_secret: "415068b05bfe34ee250b1b0fb0847a7cef7bc1e99ab407dedcf779348097210b", |
||||
|
view_key_public: "a7d037f5f73677c4d1ba32559238886c9011d682121946cf06f9bb59efe75862", |
||||
|
Address: "dEToRmE1GKxj9BVmA46whoLE5vKNnBH6BfrRoaoGLig4WjN9WHF3FCJA7QZwkkGP1KATSXC7cLB9s5EDT5Xfczdk9mV1pUkkUg", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "Italiano", |
||||
|
seed: "sospiro uomo sommario orecchio muscolo testa avido sponda mutande levare lamento frumento volpe zainetto ammirare stufa convegno patente salto venire pianeta marinaio minuto moneta moneta", |
||||
|
spend_key_secret: "21cb90e631866952954cdcba042a3ae90407c40c052cc067226df0b454933502", |
||||
|
spend_key_public: "540850fa07de29317467980349436266652e1a0d4ba9b758568428a5881a6e4a", |
||||
|
view_key_secret: "a106482cc83587c3b39f152ddfa0a447a7647b7977deb400e56166fa7fcc9c0a", |
||||
|
view_key_public: "e076d540a85fb63fdb417304effa0541de65b80883b7b773b5d736a7face10dc", |
||||
|
Address: "dEToYBF9F58eAEsRFgQjaYCGiM1ngwjiSVPTfH6c1A5D5RQuWLjg7cBH1XUaQnY9v6ipWigbhHQN6XjHK6yXdUws8ovPF3F19g", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "Nederlands", |
||||
|
seed: "veto hobo tolvrij cricket somber omaans lourdes kokhals ionisch lipman freon neptunus zimmerman rijbaan wisgerhof oudachtig nerd walraven ruis gevecht foolen onheilig rugnummer russchen cricket", |
||||
|
spend_key_secret: "921cbd7640df5fd12effb8f4269c5a47bac0ef3f75a0c25aa9f174f589801102", |
||||
|
spend_key_public: "f136d2467e0e1826218b83d148374cd215358d1fe6951eab0b6046e632170072", |
||||
|
view_key_secret: "ff10ba6ee19a563b60ac8ab5d94916993a1ff05c644c3f73056c91edd1423b06", |
||||
|
view_key_public: "7506289e53bcfaee88ce5ff5a83d2818d066db2b8d776a15808e5c3fd9a49cde", |
||||
|
Address: "dEToqunYRNu3MjViW649P5AFUquDmjZW5RwedfYZ6xbT4r9TKMQVk34YcLzXmSx4CPBEJARk23ZKzLyUDJMAzJdN7EovWv3GRd", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "Português", |
||||
|
seed: "guloso caatinga enunciar newtoniano aprumo ilogismo vazio gibi imovel mixuruca bauxita paludismo unanimidade zumbi vozes roer anzol leonardo roer ucraniano elmo paete susto taco imovel", |
||||
|
spend_key_secret: "92da2722c7138e65559973131fd2c69b4a0ae4faf0e12b7abe096d5870d6a700", |
||||
|
spend_key_public: "f2daf0540863ae830c6f994fc467900f77dfac153f36e84e9e0eaa074333a3e9", |
||||
|
view_key_secret: "2de03327764d8d8fdb210560ce3e78b6698023ea9993a104afccf34495a82506", |
||||
|
view_key_public: "2e0db07e7ea17fd49a2a92d7ca5071445033c0107f7d4f5adb9cb063b7aab7ea", |
||||
|
Address: "dERopX3LiCoHg3AFLgZB5dJKgvLESnnqLABfvPAM4u869dya9oocJGVU1kG8wQjC25ETPmRyMKw98MxfVwqxbmdY7UEGsR2czw", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "русский язык", |
||||
|
seed: "шорох рента увлекать пешеход гонка сеять пчела ваза апатия пишущий готовый вибрация юбка здоровье машина штука охрана доза рынок клоун рецепт отпуск шестерка эволюция вибрация", |
||||
|
spend_key_secret: "3d0fb729be695b865c073eed68ee91f06d429a27f8eaaaa6a99f954edbef8406", |
||||
|
spend_key_public: "c564b0e4d2992b534f796d70d38d283e3fb53cee717ecd1aad1156e2b79abc85", |
||||
|
view_key_secret: "7c048a8c4f9b1aaba092f5cbc07bded9bfe35fcad7ce46634639d042011b8b04", |
||||
|
view_key_public: "8d9f057765ab73b2ae890c5073737ba009539c8b4746a5e58e74a6cb7150a8c2", |
||||
|
Address: "dERojPZ7WjBScw9H8PS6oCQcQJBXJaQdNND8ZYbYBr2SSt8wzG8HFg8VgJKcsDonhYLKL5Q71UNWACpNiaESzsJx44HUmJzaWW", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "日本語", |
||||
|
seed: "かわく ねまき けもの せいげん ためる にんめい てあみ にりんしゃ さわやか えらい うちき けいかく あたる せっきゃく ずっしり かいよう おおや てらす くれる ばかり なこうど たいうん そまつ たいえき せいげん", |
||||
|
spend_key_secret: "e12da07065554a32ac798396f74dbb35557164f9f39291a3f95705e62e0d7703", |
||||
|
spend_key_public: "09cc0d2adecd40f1118dffce60d1f5d6876ed898ef9360e867bc1e52df36b6fb", |
||||
|
view_key_secret: "90346fc93565c41686eb23fe4fae22a89e59f2ea14d0ba8ad3b16a99ebd80e0b", |
||||
|
view_key_public: "982046c49edc082df0e44a739b831a7c0a325766f9c4fa09fbf8c984a8c6bc06", |
||||
|
Address: "dERoNDzRBZfbLDdeoKD8Zdc7svU36AKPtReksucYRpy4A9oWVcc5dFsdoaxnS7ddmtNvsL5w1eWkYZwvQqApAg8X8XomwZSLws", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "简体中文 (中国)", |
||||
|
seed: "启 写 输 苯 加 担 乳 代 集 预 懂 均 倒 革 熟 载 隆 台 幸 谋 轮 抚 扩 急 输", |
||||
|
spend_key_secret: "3bfd99190f28bd7830b3631cfa514176fc24e88281fe056ce447a5a7fcdc9a02", |
||||
|
spend_key_public: "f27221193c3ab0709009e2225578ff93d86efc178ebc0b482e8d9ec7e741df40", |
||||
|
view_key_secret: "1786f5656bc093a06d5064a80bb891e2e1873699da5e3b63bb16af2bc5563b0c", |
||||
|
view_key_public: "976d8c38f15220a3ee33724c3eb5315589b41e7b2f4b0ee2be04e92edae94418", |
||||
|
Address: "dERopUMxPjhApMpS4vt2B6MEqTpvQbZo3YTGFr7MoabYC23RE7DvTQCEjju9jXHfwBXJoBfHaCVupDZAAgZpLaY99qhsXcCFmg", |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: "Esperanto", |
||||
|
seed: "amrakonto facila vibri obtuza gondolo membro alkoholo oferti ciumi reinspekti azteka kupro gombo keglo dugongo diino hemisfero sume servilo bambuo sekretario alta diurno duloka hemisfero", |
||||
|
spend_key_secret: "61abd2a5625a95371882117d8652e0735779b7b535008c73d65735b9477b1105", |
||||
|
spend_key_public: "74484fccc824cecdb0a9e69a163938f5d075fcf4d649444e86187cde130b2f04", |
||||
|
view_key_secret: "ba6202a8b877b6c58eb7239d9a23166202ae454a9c98de74d29ba593782ce20c", |
||||
|
view_key_public: "22437d58b154e9b5f35526dbfd6d6e71769103536de248eea98df7209de9759b", |
||||
|
Address: "dERoaEnz1jm7A5kv9xFxgdAa8Y7SCqepmDFnEo4Rkwe22sVjoBThDweFCmBjkJMLSQKJd4soX6wBierFKbDTh1SL9r8XY829pb", |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
for _, test := range tests { |
||||
|
spend_key_secret := HexToKey(test.spend_key_secret) |
||||
|
spend_key_public := HexToKey(test.spend_key_public) |
||||
|
|
||||
|
if spend_key_public != *(spend_key_secret.PublicKey()) { |
||||
|
t.Errorf("%s key generation testing failed ", test.name) |
||||
|
} |
||||
|
|
||||
|
view_key_secret := HexToKey(test.view_key_secret) |
||||
|
view_key_public := HexToKey(test.view_key_public) |
||||
|
|
||||
|
if view_key_public != *(view_key_secret.PublicKey()) { |
||||
|
t.Errorf("%s key generation testing failed for spend key ", test.name) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -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,36 @@ |
|||||
|
// 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 ringct |
||||
|
|
||||
|
import "testing" |
||||
|
|
||||
|
func Test_LowOrder_KeyImage(t *testing.T) { |
||||
|
|
||||
|
k_image := HexToKey("04331738293495ffc0b6121d3c4d3b3fd2931ea0768c5f9ddc4df6867411a20d") |
||||
|
curve_order := CurveOrder() |
||||
|
mult_result := ScalarMultKey(&k_image, &curve_order) |
||||
|
|
||||
|
if *mult_result != Identity { |
||||
|
|
||||
|
t.Errorf("Low order key image Testing failed") |
||||
|
|
||||
|
} |
||||
|
// fmt.Printf("identity %s\n", ringct.Identity)
|
||||
|
// fmt.Printf("curve_order %s\n", curve_order)
|
||||
|
// fmt.Printf("mult_result %s\n", mult_result)
|
||||
|
|
||||
|
} |
@ -1,23 +1,34 @@ |
|||||
package ringct |
|
||||
|
// 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 ringct |
||||
|
|
||||
import "testing" |
import "testing" |
||||
import "math/rand" |
import "math/rand" |
||||
|
|
||||
func Test_Range_and_Borromean_Signature(t *testing.T){ |
|
||||
var c,mask Key |
|
||||
|
|
||||
for i := 0; i < 50;i++{ // test it 500 times
|
|
||||
var amount uint64 = rand.Uint64() |
|
||||
sig := ProveRange(&c,&mask,amount) |
|
||||
if VerifyRange(&c, *sig) == false { |
|
||||
t.Errorf("Range Test failed") |
|
||||
return |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
func Test_Range_and_Borromean_Signature(t *testing.T) { |
||||
|
var c, mask Key |
||||
|
|
||||
|
for i := 0; i < 50; i++ { // test it 500 times
|
||||
|
var amount uint64 = rand.Uint64() |
||||
|
sig := ProveRange(&c, &mask, amount) |
||||
|
if VerifyRange(&c, *sig) == false { |
||||
|
t.Errorf("Range Test failed") |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
|
||||
} |
} |