├── README.md ├── bootstrap.sh ├── footer.md ├── header.md ├── linearize-data.py ├── linearize-hashes.py ├── linearize-mainnet.cfg ├── linearize-testnet.cfg ├── links-mainnet.md └── links-testnet.md /README.md: -------------------------------------------------------------------------------- 1 | # bootstrap.dat files for [Dash Core](https://github.com/dashpay/dash) 2 | 3 | ### Usage 4 | 5 | 1. Download and extract one of the recent files linked below. 6 | 1. Run your wallet with `-loadblock=/path/to/bootstrap.dat` command line option and let it sync. 7 | 1. Once sync is done `bootstrap.dat` file is no longer needed and can be removed. 8 | 9 | ### Recent files 10 | 11 | #### For mainnet: 12 | 13 | Block [2280843](https://insight.dash.org/insight/block/0000000000000025650024ef8c75d0dafcddb72f5350cae8c5a56b2da9d01566): Sun Jun 1 03:00:01 AM UTC 2025 [zip](https://dash-bootstrap-2.ams3.digitaloceanspaces.com/mainnet/2025-06-01/bootstrap.dat.zip) (28G) [SHA256](https://dash-bootstrap-2.ams3.digitaloceanspaces.com/mainnet/2025-06-01/sha256.txt) 14 | 15 | Block [2264304](https://insight.dash.org/insight/block/0000000000000016028934ffe627b1c628255cf83241528be8979b6e16bd4936): Thu May 1 11:07:53 PM UTC 2025 [zip](https://dash-bootstrap-2.ams3.digitaloceanspaces.com/mainnet/2025-05-01/bootstrap.dat.zip) (28G) [SHA256](https://dash-bootstrap-2.ams3.digitaloceanspaces.com/mainnet/2025-05-01/sha256.txt) 16 | 17 | 18 | #### For testnet: 19 | 20 | Block [1261825](https://insight.testnet.networks.dash.org/insight/block/000000b9ce6d0fb4346c8df29007df5931037ec5fb1c9ef788f640dbc9a06c50): Sun Jun 1 03:31:44 AM UTC 2025 [zip](https://dash-bootstrap-2.ams3.digitaloceanspaces.com/testnet/2025-06-01/bootstrap.dat.zip) (2.1G) [SHA256](https://dash-bootstrap-2.ams3.digitaloceanspaces.com/testnet/2025-06-01/sha256.txt) 21 | 22 | Block [1243163](https://insight.testnet.networks.dash.org/insight/block/000000cca5a7883f7d08a58087d2883bc7e47d1fc2222d11959ab9a2282d59ee): Thu May 1 11:38:44 PM UTC 2025 [zip](https://dash-bootstrap-2.ams3.digitaloceanspaces.com/testnet/2025-05-01/bootstrap.dat.zip) (2.1G) [SHA256](https://dash-bootstrap-2.ams3.digitaloceanspaces.com/testnet/2025-05-01/sha256.txt) 23 | 24 | 25 | ### Donations are welcome: 26 | 27 | DASH: XsV4GHVKGTjQFvwB7c6mYsGV3Mxf7iser6 28 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | s3cmd="/usr/local/bin/s3cmd --config=/root/.s3cfg" 3 | s3name="dash-bootstrap-2" 4 | s3bucket="s3://$s3name/" 5 | s3https="https://$s3name.ams3.digitaloceanspaces.com/" 6 | file="bootstrap.dat" 7 | file_zip="$file.zip" 8 | file_sha256="sha256.txt" 9 | header=`cat header.md` 10 | footer=`cat footer.md` 11 | 12 | # pass network name as a param 13 | do_the_job() { 14 | network=$1 15 | date=`date -u` 16 | date_fmt=`date -u +%Y-%m-%d` 17 | s3networkPath="$s3bucket$network/" 18 | s3currentPath="$s3networkPath$date_fmt/" 19 | s3currentUrl="$s3https$network/$date_fmt/" 20 | linksFile="links-$network.md" 21 | prevLinks=`head -n1 $linksFile` 22 | echo "$network job - Starting..." 23 | # process blockchain 24 | ./linearize-hashes.py linearize-$network.cfg > hashlist.txt 25 | ./linearize-data.py linearize-$network.cfg 26 | # compress 27 | zip $file_zip $file 28 | # calculate checksums 29 | sha256sum $file > $file_sha256 30 | sha256sum $file_zip >> $file_sha256 31 | # store 32 | $s3cmd put $file_zip $file_sha256 $s3currentPath --acl-public 33 | # update docs 34 | url_zip=$s3currentUrl$file_zip 35 | url_sha256=$s3currentUrl$file_sha256 36 | size_zip=`ls -lh $file_zip | awk -F" " '{ print $5 }'` 37 | newLinks="Block [$blocks]($url_explorer): $date [zip]($url_zip) ($size_zip) [SHA256]($url_sha256)\n\n$prevLinks" 38 | echo -e "$newLinks" > $linksFile 39 | rm $file $file_zip $file_sha256 hashlist.txt 40 | echo -e "#### For $network:\n\n$newLinks\n\n" >> README.md 41 | # clean up old files 42 | keepDays=55 43 | scanDays=80 44 | oldFolders=$($s3cmd ls $s3networkPath | grep -oP 's3:.*') 45 | while [ $keepDays -lt $scanDays ]; do 46 | loopDate=$(date -u -d "now -"$keepDays" days" +%Y-%m-%d) 47 | found=$(echo -e $oldFolders | grep -oP $loopDate) 48 | if [ "$found" != "" ]; then 49 | echo "found old folder $found, deleting $s3networkPath$loopDate/ ..." 50 | $s3cmd del -r $s3networkPath$loopDate/ 51 | fi 52 | let keepDays=keepDays+1 53 | done 54 | echo "$network job - Done!" 55 | } 56 | 57 | # fill the header 58 | echo -e "$header\n" > README.md 59 | 60 | # mainnet 61 | #cat ~/.dash/blocks/blk0000* > $file 62 | blocks=`dash-cli getblockcount` 63 | blockhash=`dash-cli getblockhash $blocks` 64 | url_explorer="https://insight.dash.org/insight/block/$blockhash" 65 | do_the_job mainnet 66 | 67 | # testnet 68 | #cat ~/.dash/testnet3/blocks/blk0000* > $file 69 | blocks=`dash_testnet-cli -datadir=/root/.dashcore_test getblockcount` 70 | blockhash=`dash_testnet-cli -datadir=/root/.dashcore_test getblockhash $blocks` 71 | url_explorer="https://insight.testnet.networks.dash.org/insight/block/$blockhash" 72 | do_the_job testnet 73 | 74 | # finalize with the footer 75 | echo -e "$footer" >> README.md 76 | 77 | # push to github 78 | git add *.md 79 | git commit -m "$date - autoupdate" 80 | git push 81 | -------------------------------------------------------------------------------- /footer.md: -------------------------------------------------------------------------------- 1 | ### Donations are welcome: 2 | 3 | DASH: XsV4GHVKGTjQFvwB7c6mYsGV3Mxf7iser6 4 | -------------------------------------------------------------------------------- /header.md: -------------------------------------------------------------------------------- 1 | # bootstrap.dat files for [Dash Core](https://github.com/dashpay/dash) 2 | 3 | ### Usage 4 | 5 | 1. Download and extract one of the recent files linked below. 6 | 1. Run your wallet with `-loadblock=/path/to/bootstrap.dat` command line option and let it sync. 7 | 1. Once sync is done `bootstrap.dat` file is no longer needed and can be removed. 8 | 9 | ### Recent files 10 | -------------------------------------------------------------------------------- /linearize-data.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # linearize-data.py: Construct a linear, no-fork version of the chain. 4 | # 5 | # Copyright (c) 2013-2014 The Bitcoin Core developers 6 | # Distributed under the MIT software license, see the accompanying 7 | # file COPYING or http://www.opensource.org/licenses/mit-license.php. 8 | # 9 | 10 | import struct 11 | import re 12 | import os 13 | import os.path 14 | import sys 15 | import dash_hash 16 | import datetime 17 | import time 18 | import glob 19 | from collections import namedtuple 20 | from binascii import unhexlify 21 | 22 | settings = {} 23 | 24 | def hex_switchEndian(s): 25 | """ Switches the endianness of a hex string (in pairs of hex chars) """ 26 | pairList = [s[i:i+2].encode() for i in range(0, len(s), 2)] 27 | return b''.join(pairList[::-1]).decode() 28 | 29 | def uint32(x): 30 | return x & 0xffffffff 31 | 32 | def bytereverse(x): 33 | return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | 34 | (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )) 35 | 36 | def bufreverse(in_buf): 37 | out_words = [] 38 | for i in range(0, len(in_buf), 4): 39 | word = struct.unpack('@I', in_buf[i:i+4])[0] 40 | out_words.append(struct.pack('@I', bytereverse(word))) 41 | return b''.join(out_words) 42 | 43 | def wordreverse(in_buf): 44 | out_words = [] 45 | for i in range(0, len(in_buf), 4): 46 | out_words.append(in_buf[i:i+4]) 47 | out_words.reverse() 48 | return b''.join(out_words) 49 | 50 | def calc_hdr_hash(blk_hdr): 51 | #hash1 = hashlib.sha256() 52 | #hash1.update(blk_hdr) 53 | #hash1_o = hash1.digest() 54 | 55 | #hash2 = hashlib.sha256() 56 | #hash2.update(hash1_o) 57 | #hash2_o = hash2.digest() 58 | 59 | #return hash2_o 60 | pow_hash = dash_hash.getPoWHash(blk_hdr) 61 | return pow_hash 62 | 63 | def calc_hash_str(blk_hdr): 64 | hash = calc_hdr_hash(blk_hdr) 65 | hash = bufreverse(hash) 66 | hash = wordreverse(hash) 67 | hash_str = hash.hex() 68 | return hash_str 69 | 70 | def get_blk_dt(blk_hdr): 71 | members = struct.unpack(" self.maxOutSz): 162 | self.outF.close() 163 | if self.setFileTime: 164 | os.utime(self.outFname, (int(time.time()), self.highTS)) 165 | self.outF = None 166 | self.outFname = None 167 | self.outFn = self.outFn + 1 168 | self.outsz = 0 169 | 170 | (blkDate, blkTS) = get_blk_dt(blk_hdr) 171 | if self.timestampSplit and (blkDate > self.lastDate): 172 | print("New month " + blkDate.strftime("%Y-%m") + " @ " + self.hash_str) 173 | self.lastDate = blkDate 174 | if self.outF: 175 | self.outF.close() 176 | if self.setFileTime: 177 | os.utime(self.outFname, (int(time.time()), self.highTS)) 178 | self.outF = None 179 | self.outFname = None 180 | self.outFn = self.outFn + 1 181 | self.outsz = 0 182 | 183 | if not self.outF: 184 | if self.fileOutput: 185 | self.outFname = self.settings['output_file'] 186 | else: 187 | self.outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn) 188 | print("Output file " + self.outFname) 189 | self.outF = open(self.outFname, "wb") 190 | 191 | self.outF.write(inhdr) 192 | self.outF.write(blk_hdr) 193 | self.outF.write(rawblock) 194 | self.outsz = self.outsz + len(inhdr) + len(blk_hdr) + len(rawblock) 195 | 196 | self.blkCountOut = self.blkCountOut + 1 197 | if blkTS > self.highTS: 198 | self.highTS = blkTS 199 | 200 | if (self.blkCountOut % 1000) == 0: 201 | print('%i blocks scanned, %i blocks written (of %i, %.1f%% complete)' % 202 | (self.blkCountIn, self.blkCountOut, len(self.blkindex), 100.0 * self.blkCountOut / len(self.blkindex))) 203 | 204 | def inFileName(self, fn): 205 | return os.path.join(self.settings['input'], "blk%05d.dat" % fn) 206 | 207 | def fetchBlock(self, extent): 208 | '''Fetch block contents from disk given extents''' 209 | with open(self.inFileName(extent.fn), "rb") as f: 210 | f.seek(extent.offset) 211 | return f.read(extent.size) 212 | 213 | def copyOneBlock(self): 214 | '''Find the next block to be written in the input, and copy it to the output.''' 215 | extent = self.blockExtents.pop(self.blkCountOut) 216 | if self.blkCountOut in self.outOfOrderData: 217 | # If the data is cached, use it from memory and remove from the cache 218 | rawblock = self.outOfOrderData.pop(self.blkCountOut) 219 | self.outOfOrderSize -= len(rawblock) 220 | else: # Otherwise look up data on disk 221 | rawblock = self.fetchBlock(extent) 222 | 223 | self.writeBlock(extent.inhdr, extent.blkhdr, rawblock) 224 | 225 | def run(self): 226 | while self.blkCountOut < len(self.blkindex): 227 | if not self.inF: 228 | fname = self.inFileName(self.inFn) 229 | print("Input file " + fname) 230 | try: 231 | self.inF = open(fname, "rb") 232 | except IOError: 233 | print("Premature end of block data") 234 | return 235 | 236 | inhdr = self.inF.read(8) 237 | if (not inhdr or (inhdr[0] == "\0")): 238 | self.inF.close() 239 | self.inF = None 240 | self.inFn = self.inFn + 1 241 | continue 242 | 243 | inMagic = inhdr[:4] 244 | if (inMagic != self.settings['netmagic']): 245 | # Seek backwards 7 bytes (skipping the first byte in the previous search) 246 | # and continue searching from the new position if the magic bytes are not 247 | # found. 248 | self.inF.seek(-7, os.SEEK_CUR) 249 | continue 250 | inLenLE = inhdr[4:] 251 | su = struct.unpack("