コード例 #1
0
ファイル: cash_request_in.go プロジェクト: dzyk/dcoin-go
/* не забываем, что cash_request_OUT_front проверяет формат amount,
 * можно ли делать запрос указанному юзеру, есть ли у юзера
 * обещанные суммы на сумму amount, есть ли нужное кол-во DC у отправителя,
 * является ли отправитель майнером
 *
 * */
func (p *Parser) CashRequestInFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	// code может быть чем угодно, т.к. отправитель шлет в сеть лишь хэш
	// нигде, кроме cash_request_in_front, code не используется
	// if ( !check_input_data ($this->tx_data['code'], 'cash_code') )
	//	return 'cash_request_in_front code';

	verifyData := map[string]string{"cash_request_id": "bigint"}
	err = p.CheckInputData(verifyData)
	if err != nil {
		return p.ErrInfo(err)
	}

	var to_user_id, cTime int64
	var status string
	var hash_code []byte
	err = p.QueryRow(p.FormatQuery("SELECT to_user_id, status, hash_code, time FROM cash_requests WHERE id  =  ?"), p.TxMaps.Int64["cash_request_id"]).Scan(&to_user_id, &status, &hash_code, &cTime)
	if err != nil && err != sql.ErrNoRows {
		return p.ErrInfo(err)
	}

	// ID cash_requests юзер указал сам, значит это может быть случайное число.
	// проверим, является получателем наш юзер
	if to_user_id != p.TxUserID {
		return p.ErrInfo("to_user_id!=user_id")
	}
	// должно быть pending
	if status != "pending" {
		return p.ErrInfo("status!=pending")
	}
	// проверим код
	if !bytes.Equal(utils.DSha256(p.TxMaps.String["code"]), utils.BinToHex(hash_code)) {
		return p.ErrInfo("code!=hash_code")
	}
	var txTime int64
	if p.BlockData != nil { // тр-ия пришла в блоке
		txTime = p.BlockData.Time
	} else {
		txTime = time.Now().Unix() // просто на всякий случай небольшой запас
	}
	// запрос может быть принят, только если он был отправлен не позднее чем через cash_request_time сек назад
	if cTime < txTime-p.Variables.Int64["cash_request_time"] {
		return p.ErrInfo(fmt.Sprintf("%d < %d - %d", cTime, txTime, p.Variables.Int64["cash_request_time"]))
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["cash_request_id"], p.TxMap["code"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}
	return nil
}
コード例 #2
0
ファイル: e_signup.go プロジェクト: dzyk/dcoin-go
func (c *Controller) ESignUp() (string, error) {

	c.r.ParseForm()
	email := c.r.FormValue("email")
	password := c.r.FormValue("password")
	if len(password) > 50 || len(password) < 1 {
		return "", errors.New(c.Lang["invalid_pass"])
	}

	existsEmail, err := c.Single("SELECT id FROM e_users WHERE email = ?", email).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	if existsEmail > 0 {
		return "", errors.New(c.Lang["exists_email"])
	}

	salt := utils.RandSeq(32)
	passAndSalt := utils.DSha256(password + salt)
	userId, err := c.ExecSqlGetLastInsertId("INSERT INTO e_users ( email, password, ip, salt ) VALUES ( ?, ?, ?, ? )", "id", email, passAndSalt, c.r.RemoteAddr, salt)
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	c.sess.Set("e_user_id", userId)

	return utils.JsonAnswer("success", "success").String(), nil
}
コード例 #3
0
ファイル: login.go プロジェクト: dzyk/dcoin-go
func (c *Controller) Login() (string, error) {

	var pool_tech_works int

	funcMap := template.FuncMap{
		"noescape": func(s string) template.HTML {
			return template.HTML(s)
		},
	}

	data, err := static.Asset("static/templates/login.html")
	if err != nil {
		return "", err
	}
	modal, err := static.Asset("static/templates/modal.html")
	if err != nil {
		return "", err
	}

	t := template.Must(template.New("template").Funcs(funcMap).Parse(string(data)))
	t = template.Must(t.Parse(string(modal)))

	b := new(bytes.Buffer)

	// есть ли установочный пароль и был ли начально записан ключ
	var setupPassword bool
	if !c.Community {
		setupPassword_, err := c.Single("SELECT setup_password FROM config").String()
		if err != nil {
			return "", err
		}
		myKey, err := c.GetMyPublicKey(c.MyPrefix)
		if err != nil {
			return "", err
		}
		if len(myKey) == 0 && (len(setupPassword_) > 0 || setupPassword_ == string(utils.DSha256(""))) {
			setupPassword = true
		}
	}
	//fmt.Println(c.Lang)
	// проверим, не идут ли тех. работы на пуле
	if len(c.NodeConfig["pool_admin_user_id"]) > 0 && c.NodeConfig["pool_admin_user_id"] != utils.Int64ToStr(c.UserId) && c.NodeConfig["pool_tech_works"] == "1" && c.Community {
		pool_tech_works = 1
	} else {
		pool_tech_works = 0
	}
	err = t.ExecuteTemplate(b, "login", &loginStruct{
		Lang:          c.Lang,
		MyModalIdName: "myModalLogin",
		UserID:        c.UserId,
		PoolTechWorks: pool_tech_works,
		SetupPassword: setupPassword,
		Community:     c.Community,
		Desktop:       utils.Desktop(),
		Mobile:        utils.Mobile()})
	if err != nil {
		return "", err
	}
	return b.String(), nil
}
コード例 #4
0
ファイル: block_explorer.go プロジェクト: dzyk/dcoin-go
func (c *Controller) BlockExplorer() (string, error) {

	var err error

	blockId := int64(utils.StrToFloat64(c.Parameters["blockId"]))
	start := int64(utils.StrToFloat64(c.Parameters["start"]))

	var data, sql string
	if start > 0 || (start == 0 && blockId == 0) {
		if start == 0 && blockId == 0 {
			data += "<h3>Latest Blocks</h3>"
			sql = `	SELECT data,  hash
						FROM block_chain
						ORDER BY id DESC
						LIMIT 15`
		} else {
			sql = `	SELECT data,  hash
						FROM block_chain
						ORDER BY id ASC
						LIMIT ` + utils.Int64ToStr(start-1) + `, 100`
		}
		data += `<table class="table"><tr><th>Block</th><th>Hash</th><th>Time</th><th><nobr>User id</nobr></th><th><nobr>Miner id</nobr></th><th>Level</th><th>Transactions</th></tr>`
		blocksChain, err := c.GetAll(sql, -1)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		for _, blockData := range blocksChain {
			hash := utils.BinToHex([]byte(blockData["hash"]))
			binaryData := []byte(blockData["data"])
			parser := new(dcparser.Parser)
			parser.DCDB = c.DCDB
			parser.BinaryData = binaryData
			err = parser.ParseDataLite()
			parser.BlockData.Sign = utils.BinToHex(parser.BlockData.Sign)
			minerId, err := c.GetMinerId(parser.BlockData.UserId)
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			data += fmt.Sprintf(`<tr><td><a href="#" onclick="dc_navigate('blockExplorer', {'blockId':%d})">%d</a></td><td>%s</td><td><nobr><span class='unixtime'>%d</span></nobr></td><td>%d</td><td>%d</td><td>%d</td><td>`, parser.BlockData.BlockId, parser.BlockData.BlockId, hash, parser.BlockData.Time, parser.BlockData.UserId, minerId, parser.BlockData.Level)
			data += utils.IntToStr(len(parser.TxMapArr))
			data += "</td></tr>"
		}
		data += "</table>"
	} else if blockId > 0 {
		data += `<table class="table">`
		blockChain, err := c.OneRow("SELECT data, hash, cur_0l_miner_id, max_miner_id FROM block_chain WHERE id = ?", blockId).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		binToHexArray := []string{"sign", "public_key", "encrypted_message", "comment", "bin_public_keys"}
		hash := utils.BinToHex([]byte(blockChain["hash"]))
		binaryData := blockChain["data"]
		parser := new(dcparser.Parser)
		parser.DCDB = c.DCDB
		parser.BinaryData = []byte(binaryData)
		err = parser.ParseDataLite()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		parser.BlockData.Sign = utils.BinToHex(parser.BlockData.Sign)
		previous := parser.BlockData.BlockId - 1
		next := parser.BlockData.BlockId + 1
		levelsRange := utils.GetBlockGeneratorMinerIdRange(utils.StrToInt64(blockChain["cur_0l_miner_id"]), utils.StrToInt64(blockChain["max_miner_id"]))
		minerId, err := c.GetMinerId(parser.BlockData.UserId)
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		_, _, _, CurrentUserId, _, _, _ := c.TestBlock()
		maxMinerId, err := c.Single("SELECT max(miner_id) FROM miners").Int64()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		currentMinerId, err := c.Single("SELECT miner_id FROM miners_data WHERE user_id = ?", CurrentUserId).Int64()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		NextBlockLevelsRange := utils.GetBlockGeneratorMinerIdRange(currentMinerId, maxMinerId)

		data += fmt.Sprintf(`<tr><td><strong>Raw&nbsp;data</strong></td><td><a href='ajax?controllerName=getBlock&id=%d&download=1' target='_blank'>Download</a></td></tr>`, parser.BlockData.BlockId)
		data += fmt.Sprintf(`<tr><td><strong>Block_id</strong></td><td>%d (<a href="#" onclick="dc_navigate('blockExplorer', {'blockId':%d})">Previous</a> / <a href="#" onclick="dc_navigate('blockExplorer', {'blockId':%d})">Next</a> )</td></tr>`, parser.BlockData.BlockId, previous, next)
		data += fmt.Sprintf(`<tr><td><strong>Hash</strong></td><td>%s</td></tr>`, hash)
		data += fmt.Sprintf(`<tr><td><strong>Time</strong></td><td><span class='unixtime'>%d</span> / %d</td></tr>`, parser.BlockData.Time, parser.BlockData.Time)
		data += fmt.Sprintf(`<tr><td><strong>User_id</strong></td><td>%d</td></tr>`, parser.BlockData.UserId)
		data += fmt.Sprintf(`<tr><td><strong>Miner_Id</strong></td><td>%d</td></tr>`, minerId)
		data += fmt.Sprintf(`<tr><td><strong>Level</strong></td><td>%d (%v) next: %v</td></tr>`, parser.BlockData.Level, levelsRange, NextBlockLevelsRange)
		data += fmt.Sprintf(`<tr><td><strong>Sign</strong></td><td>%s</td></tr>`, parser.BlockData.Sign)
		if len(parser.TxMapArr) > 0 {
			data += `<tr><td><strong>Transactions</strong></td><td><div><pre style='width: 700px'>`
			for i := 0; i < len(parser.TxMapArr); i++ {
				for k, data_ := range parser.TxMapArr[i] {
					if utils.InSliceString(k, binToHexArray) {
						parser.TxMapArr[i][k] = utils.BinToHex(data_)
					}
					if k == "file" {
						parser.TxMapArr[i][k] = []byte("file size: " + utils.IntToStr(len(data_)))
					} else if k == "code" {
						parser.TxMapArr[i][k] = utils.DSha256(data_)
					} else if k == "secret" {
						parser.TxMapArr[i][k] = utils.BinToHex(data_)
					}
					data += fmt.Sprintf("%v : %s\n", k, parser.TxMapArr[i][k])
				}
				data += "\n\n"
			}

			data += "</pre></div></td></tr>"
		}
		data += "</table>"
	}

	// пока панель тут
	myNotice := make(map[string]string)
	if c.SessUserId > 0 {
		myNotice, err = c.GetMyNoticeData(c.SessUserId, c.SessUserId, c.MyPrefix, c.Lang)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
	}

	TemplateStr, err := makeTemplate("block_explorer", "blockExplorer", &BlockExplorerPage{
		Lang:           c.Lang,
		CurrencyList:   c.CurrencyListCf,
		MyNotice:       myNotice,
		Data:           data,
		Start:          start,
		BlockId:        blockId,
		PoolAdmin:      c.PoolAdmin,
		SessRestricted: c.SessRestricted,
		UserId:         c.SessUserId})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
コード例 #5
0
ファイル: node_voting.go プロジェクト: dzyk/dcoin-go
func NodeVoting(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	const GoroutineName = "NodeVoting"
	d := new(daemon)
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}
	d.goRoutineName = GoroutineName
	d.chAnswer = chAnswer
	d.chBreaker = chBreaker
	if utils.Mobile() {
		d.sleepTime = 3600
	} else {
		d.sleepTime = 60
	}
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

	err = d.notMinerSetSleepTime(1800)
	if err != nil {
		log.Error("%v", err)
		return
	}

BEGIN:
	for {
		log.Info(GoroutineName)
		MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())}

		// проверим, не нужно ли нам выйти из цикла
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}

		err, restart := d.dbLock()
		if restart {
			break BEGIN
		}
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		// берем данные, которые находятся на голосовании нодов
		rows, err := d.Query(d.FormatQuery(`
				SELECT miners_data.user_id,
							 http_host as host,
							 face_hash,
							 profile_hash,
							 photo_block_id,
							 photo_max_miner_id,
							 miners_keepers,
							 id as vote_id,
							 miner_id
				FROM votes_miners
				LEFT JOIN miners_data
						 ON votes_miners.user_id = miners_data.user_id
				WHERE cron_checked_time < ? AND
							 votes_end = 0 AND
							 type = 'node_voting'
				`), utils.Time()-consts.CRON_CHECKED_TIME_SEC)
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		if ok := rows.Next(); ok {
			var vote_id, miner_id int64
			var user_id, host, row_face_hash, row_profile_hash, photo_block_id, photo_max_miner_id, miners_keepers string
			err = rows.Scan(&user_id, &host, &row_face_hash, &row_profile_hash, &photo_block_id, &photo_max_miner_id, &miners_keepers, &vote_id, &miner_id)
			if err != nil {
				rows.Close()
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}

			// проверим, не нужно нам выйти, т.к. обновилась версия софта
			if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
				rows.Close()
				utils.Sleep(1)
				break
			}
			minersIds := utils.GetMinersKeepers(photo_block_id, photo_max_miner_id, miners_keepers, true)
			myUsersIds, err := d.GetMyUsersIds(true, true)
			myMinersIds, err := d.GetMyMinersIds(myUsersIds)

			// нет ли нас среди тех, кто должен скачать фото к себе и проголосовать
			var intersectMyMiners []int64
			for _, id := range minersIds {
				if utils.InSliceInt64(int64(id), myMinersIds) {
					intersectMyMiners = append(intersectMyMiners, int64(id))
				}
			}
			var vote int64
			if len(intersectMyMiners) > 0 {
				var downloadError bool
				var faceHash, profileHash string
				var faceFile, profileFile []byte
				// копируем фото  к себе
				profilePath := *utils.Dir + "/public/profile_" + user_id + ".jpg"
				_, err = utils.DownloadToFile(host+"/public/"+user_id+"_user_profile.jpg", profilePath, 60, chBreaker, chAnswer, GoroutineName)
				if err != nil {
					log.Error("%s", utils.ErrInfo(err))
					downloadError = true
				}
				facePath := *utils.Dir + "/public/face_" + user_id + ".jpg"
				_, err = utils.DownloadToFile(host+"/public/"+user_id+"_user_face.jpg", facePath, 60, chBreaker, chAnswer, GoroutineName)
				if err != nil {
					log.Error("%s", utils.ErrInfo(err))
					downloadError = true
				}
				if !downloadError {
					// хэши скопированных фото
					profileFile, err = ioutil.ReadFile(profilePath)
					if err != nil {
						rows.Close()
						if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					profileHash = string(utils.DSha256(profileFile))
					log.Info("%v", "profileHash", profileHash)
					faceFile, err = ioutil.ReadFile(facePath)
					if err != nil {
						rows.Close()
						if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					faceHash = string(utils.DSha256(faceFile))
					log.Info("%v", "faceHash", faceHash)
				}
				// проверяем хэш. Если сходится, то голосуем за, если нет - против и размер не должен быть более 200 Kb.
				if profileHash == row_profile_hash && faceHash == row_face_hash && len(profileFile) < 204800 && len(faceFile) < 204800 {
					vote = 1
				} else {
					log.Error("%s %s %s %s %d %d", profileHash, row_face_hash, faceHash, row_profile_hash, len(profileFile), len(faceFile))
					vote = 0 // если хэш не сходится, то удаляем только что скаченное фото
					os.Remove(profilePath)
					os.Remove(facePath)
				}

				// проходимся по всем нашим майнерам, если это пул и по одному, если это сингл-мод
				for _, myMinerId := range intersectMyMiners {

					myUserId, err := d.Single("SELECT user_id FROM miners_data WHERE miner_id  =  ?", myMinerId).Int64()
					if err != nil {
						rows.Close()
						if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}

					curTime := utils.Time()

					forSign := fmt.Sprintf("%v,%v,%v,%v,%v", utils.TypeInt("VotesNodeNewMiner"), curTime, myUserId, vote_id, vote)
					binSign, err := d.GetBinSign(forSign, myUserId)
					if err != nil {
						rows.Close()
						if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					data := utils.DecToBin(utils.TypeInt("VotesNodeNewMiner"), 1)
					data = append(data, utils.DecToBin(curTime, 4)...)
					data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(myUserId))...)
					data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(vote_id))...)
					data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(vote))...)
					data = append(data, utils.EncodeLengthPlusData([]byte(binSign))...)

					err = d.InsertReplaceTxInQueue(data)
					if err != nil {
						rows.Close()
						if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}

				}
			}

			// отмечаем, чтобы больше не брать эту строку
			err = d.ExecSql("UPDATE votes_miners SET cron_checked_time = ? WHERE id = ?", utils.Time(), vote_id)
			if err != nil {
				rows.Close()
				if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
		}
		rows.Close()
		d.dbUnlock()

		if d.dSleep(d.sleepTime) {
			break BEGIN
		}
	}
	log.Debug("break BEGIN %v", GoroutineName)

}
コード例 #6
0
ファイル: check_setup_password.go プロジェクト: dzyk/dcoin-go
func (c *Controller) CheckSetupPassword() (string, error) {

	c.r.ParseForm()
	password, err := c.Single(`SELECT setup_password FROM config WHERE setup_password = ?`, utils.DSha256(c.r.FormValue("password"))).String()
	if err != nil {
		return "", err
	}
	if len(password) > 0 && !c.Community {
		userId, err := c.GetMyUserId("")
		if err != nil {
			return "", err
		}
		publicKey, err := c.GetUserPublicKey(userId)
		if err != nil {
			return "", err
		}
		c.sess.Set("user_id", userId)
		c.sess.Set("public_key", string(utils.BinToHex(publicKey)))
		log.Debug("public_key check: %s", string(utils.BinToHex(publicKey)))
		return "ok", nil
	}
	return "", nil

}
コード例 #7
0
ファイル: type11.go プロジェクト: dzyk/dcoin-go
func (t *TcpServer) Type11() {

	/* Получаем данные от send_to_pool */
	log.Debug("Type11")
	// размер данных
	buf := make([]byte, 4)
	_, err := t.Conn.Read(buf)
	if err != nil {
		log.Error("%v", utils.ErrInfo(err))
		return
	}
	size := utils.BinToDec(buf)
	log.Debug("size: %d", size)
	if size < 32<<20 {
		// сами данные
		log.Debug("read data")
		binaryData := make([]byte, size)
		//binaryData, err = ioutil.ReadAll(t.Conn)
		_, err = io.ReadFull(t.Conn, binaryData)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			return
		}
		//log.Debug("binaryData %x", binaryData)
		userId := utils.BinToDec(utils.BytesShift(&binaryData, 5))
		log.Debug("userId %d", userId)
		// проверим, есть ли такой юзер на пуле
		inPool, err := t.Single(`SELECT user_id FROM community WHERE user_id=?`, userId).Int64()
		if inPool <= 0 {
			log.Error("%v", utils.ErrInfo("inPool<=0"))
			_, err = t.Conn.Write(utils.DecToBin(0, 1))
			return
		}
		log.Debug("inPool %d", inPool)
		filesSign := utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData))
		log.Debug("filesSign %x", filesSign)
		forSign := ""
		var files []string
		for i := 0; i < 3; i++ {
			size := utils.DecodeLength(&binaryData)
			log.Debug("size %d", size)
			data := utils.BytesShift(&binaryData, size)
			//log.Debug("data %x", data)
			fileType := utils.BinToDec(utils.BytesShift(&data, 1))
			log.Debug("fileType %d", fileType)
			var name string
			switch fileType {
			case 0:
				name = utils.Int64ToStr(userId) + "_user_face.jpg"
			case 1:
				name = utils.Int64ToStr(userId) + "_user_profile.jpg"
			case 2:
				name = utils.Int64ToStr(userId) + "_user_video.mp4"
				/*case 3:
					name = utils.Int64ToStr(userId)+"_user_video.webm"
				case 4:
					name = utils.Int64ToStr(userId)+"_user_video.ogv"*/
			}
			forSign = forSign + string(utils.DSha256((data))) + ","
			log.Debug("forSign %s", forSign)
			err = ioutil.WriteFile(os.TempDir()+"/"+name, data, 0644)
			if err != nil {
				log.Error("%v", utils.ErrInfo(err))
				return
			}
			files = append(files, name)
			log.Debug("files %d", files)
			if len(binaryData) == 0 {
				break
			}
		}

		if len(forSign) == 0 {
			log.Error("%v", utils.ErrInfo("len(forSign) == 0"))
			_, err = t.Conn.Write(utils.DecToBin(0, 1))
			return
		}
		if len(files) == 3 {
			forSign = forSign[:len(forSign)-1]
		}
		// проверим подпись
		publicKey, err := t.GetUserPublicKey(userId)
		resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin(filesSign), true)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			_, err = t.Conn.Write(utils.DecToBin(0, 1))
			return
		}
		if resultCheckSign {
			for i := 0; i < len(files); i++ {
				utils.CopyFileContents(os.TempDir()+"/"+files[i], *utils.Dir+"/public/"+files[i])
			}
		} else {
			for i := 0; i < len(files); i++ {
				os.Remove(os.TempDir() + "/" + files[i])
			}
		}

		// и возвращаем статус
		_, err = t.Conn.Write(utils.DecToBin(1, 1))
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			return
		}
	} else {
		log.Error("%v", utils.ErrInfo("size>32mb"))
	}
}
コード例 #8
0
ファイル: upload_video.go プロジェクト: dzyk/dcoin-go
func (c *Controller) UploadVideo() (string, error) {

	if c.SessRestricted != 0 {
		return "", utils.ErrInfo(errors.New("Permission denied"))
	}

	var binaryVideo []byte

	c.r.ParseMultipartForm(32 << 20)
	file, _, err := c.r.FormFile("file")
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	videoBuffer := new(bytes.Buffer)
	_, err = io.Copy(videoBuffer, file)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer file.Close()
	binaryVideo = videoBuffer.Bytes()
	fmt.Println(c.r.MultipartForm.File["file"][0].Filename)
	fmt.Println(c.r.MultipartForm.File["file"][0].Header.Get("Content-Type"))
	fmt.Println(c.r.MultipartForm.Value["type"][0])

	var contentType, videoType string
	if _, ok := c.r.MultipartForm.File["file"]; ok {
		contentType = c.r.MultipartForm.File["file"][0].Header.Get("Content-Type")
	}
	if _, ok := c.r.MultipartForm.Value["type"]; ok {
		videoType = c.r.MultipartForm.Value["type"][0]
	}
	end := "mp4"
	switch contentType {
	case "video/mp4", "video/quicktime":
		end = "mp4"
	case "video/ogg":
		end = "ogv"
	case "video/webm":
		end = "webm"
	case "video/3gpp":

		fmt.Println("3gpp")
		conn, err := net.DialTimeout("tcp", "3gp.dcoin.club:8099", 5*time.Second)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		defer conn.Close()

		conn.SetReadDeadline(time.Now().Add(240 * time.Second))
		conn.SetWriteDeadline(time.Now().Add(240 * time.Second))

		// в 4-х байтах пишем размер данных, которые пошлем далее
		size := utils.DecToBin(len(videoBuffer.Bytes()), 4)
		_, err = conn.Write(size)
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		// далее шлем сами данные
		_, err = conn.Write(videoBuffer.Bytes())
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		// в ответ получаем размер данных, которые нам хочет передать сервер
		buf := make([]byte, 4)
		n, err := conn.Read(buf)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		log.Debug("dataSize buf: %x / get: %v", buf, n)

		// и если данных менее 10мб, то получаем их
		dataSize := utils.BinToDec(buf)
		var binaryBlock []byte
		log.Debug("dataSize: %v", dataSize)
		if dataSize < 10485760 && dataSize > 0 {
			binaryBlock = make([]byte, dataSize)
			//binaryBlock, err = ioutil.ReadAll(conn)
			_, err = io.ReadFull(conn, binaryBlock)
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			log.Debug("len(binaryBlock):", len(binaryBlock))
			binaryVideo = binaryBlock
		}
	}

	log.Debug(videoType, end)

	var name string
	if videoType == "user_video" {
		name = "public/" + utils.Int64ToStr(c.SessUserId) + "_user_video." + end
	} else {
		x := strings.Split(videoType, "-")
		if len(x) < 2 {
			if err != nil {
				return "", utils.ErrInfo(err)
			}
		}
		name = "public/" + utils.Int64ToStr(c.SessUserId) + "_promised_amount_" + x[1] + "." + end
	}
	log.Debug(*utils.Dir + "/" + name)
	err = ioutil.WriteFile(*utils.Dir+"/"+name, binaryVideo, 0644)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return utils.JsonAnswer(string(utils.DSha256(binaryVideo)), "success").String(), nil
}
コード例 #9
0
ファイル: install_step_1.go プロジェクト: dzyk/dcoin-go
// Шаг 1 - выбор либо стандартных настроек (sqlite и блокчейн с сервера) либо расширенных - pg/mysql и загрузка с нодов
func (c *Controller) InstallStep1() (string, error) {

	c.r.ParseForm()
	installType := c.r.FormValue("type")
	url := c.r.FormValue("url")
	setupPassword := c.r.FormValue("setup_password")
	userId := utils.StrToInt64(c.r.FormValue("user_id"))
	firstLoad := c.r.FormValue("first_load")
	dbType := c.r.FormValue("db_type")
	dbHost := c.r.FormValue("host")
	dbPort := c.r.FormValue("port")
	dbName := c.r.FormValue("db_name")
	dbUsername := c.r.FormValue("username")
	dbPassword := c.r.FormValue("password")
	sqliteDbUrl := c.r.FormValue("sqlite_db_url")
	keyPassword := c.r.FormValue("key_password")

	if installType == "standard" {
		dbType = "sqlite"
	} else {
		if len(url) == 0 {
			url = consts.BLOCKCHAIN_URL
		}
	}

	if _, err := os.Stat(*utils.Dir + "/config.ini"); os.IsNotExist(err) {
		ioutil.WriteFile(*utils.Dir+"/config.ini", []byte(``), 0644)
	}
	confIni, err := config.NewConfig("ini", *utils.Dir+"/config.ini")
	//confIni.Set("sql_log", "1")
	confIni.Set("error_log", "1")
	confIni.Set("log_level", "DEBUG")
	confIni.Set("log", "0")
	confIni.Set("log_block_id_begin", "0")
	confIni.Set("log_block_id_end", "0")
	confIni.Set("bad_tx_log", "1")
	confIni.Set("nodes_ban_exit", "0")
	confIni.Set("log_tables", "")
	confIni.Set("log_fns", "")
	confIni.Set("sign_hash", "ip")
	if len(sqliteDbUrl) > 0 && dbType == "sqlite" {
		utils.SqliteDbUrl = sqliteDbUrl
	}

	if dbType == "sqlite" {
		confIni.Set("db_type", "sqlite")
		confIni.Set("db_user", "")
		confIni.Set("db_host", "")
		confIni.Set("db_port", "")
		confIni.Set("db_password", "")
		confIni.Set("db_name", "")
	} else if dbType == "postgresql" || dbType == "mysql" {
		confIni.Set("db_type", dbType)
		confIni.Set("db_user", dbUsername)
		confIni.Set("db_host", dbHost)
		confIni.Set("db_port", dbPort)
		confIni.Set("db_password", dbPassword)
		confIni.Set("db_name", dbName)
	}

	err = confIni.SaveConfigFile(*utils.Dir + "/config.ini")
	if err != nil {
		return "", err
	}

	log.Debug("sqliteDbUrl: %s", sqliteDbUrl)

	go func() {

		configIni, err = confIni.GetSection("default")

		if dbType == "sqlite" && len(sqliteDbUrl) > 0 {
			if utils.DB != nil && utils.DB.DB != nil {
				utils.DB.Close()
				log.Debug("DB CLOSE")
			}
			for i := 0; i < 5; i++ {
				log.Debug("sqliteDbUrl %v", sqliteDbUrl)
				_, err := utils.DownloadToFile(sqliteDbUrl, *utils.Dir+"/litedb.db", 3600, nil, nil, "install")
				if err != nil {
					log.Error("%v", utils.ErrInfo(err))
				}
				if err == nil {
					break
				}
			}
			if err != nil {
				panic(err)
				os.Exit(1)
			}
			utils.DB, err = utils.NewDbConnect(configIni)
			log.Debug("DB OPEN")
			log.Debug("%v", utils.DB)
			if err != nil {
				log.Error("%v", utils.ErrInfo(err))
				panic(err)
				os.Exit(1)
			}
		} else {
			utils.DB, err = utils.NewDbConnect(configIni)
		}

		c.DCDB = utils.DB
		if c.DCDB.DB == nil {
			err = fmt.Errorf("utils.DB == nil")
			log.Error("%v", utils.ErrInfo(err))
			panic(err)
			os.Exit(1)
		}

		if dbType != "sqlite" || len(sqliteDbUrl) == 0 {
			schema_ := &schema.SchemaStruct{}
			schema_.DCDB = c.DCDB
			schema_.DbType = dbType
			schema_.PrefixUserId = 0
			schema_.GetSchema()

			err = c.DCDB.ExecSql(`INSERT INTO admin (user_id) VALUES (1)`)
			if err != nil {
				log.Error("%v", utils.ErrInfo(err))
				panic(err)
				os.Exit(1)
			}
		}

		//if len(userId)>0 {
		err = c.DCDB.ExecSql("INSERT INTO my_table (user_id, key_password) VALUES (?, ?)", userId, keyPassword)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			panic(err)
			os.Exit(1)
		}
		//}
		log.Debug("setupPassword: (%s) / (%s)", setupPassword, utils.DSha256(setupPassword))
		if len(setupPassword) > 0 {
			setupPassword = string(utils.DSha256(setupPassword))
		}
		err = c.DCDB.ExecSql("INSERT INTO config (sqlite_db_url, first_load_blockchain, first_load_blockchain_url, setup_password, auto_reload, chat_enabled) VALUES (?, ?, ?, ?, ?, ?)", sqliteDbUrl, firstLoad, url, setupPassword, 259200, 1)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			panic(err)
			os.Exit(1)
		}

		count, err := c.Single(`SELECT count(*) FROM payment_systems`).Int64()
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			panic(err)
			os.Exit(1)
		}
		if count == 0 {
			err = c.DCDB.ExecSql("INSERT INTO payment_systems (name)VALUES ('Adyen'),('Alipay'),('Amazon Payments'),('AsiaPay'),('Atos'),('Authorize.Net'),('BIPS'),('BPAY'),('Braintree'),('CentUp'),('Chargify'),('Citibank'),('ClickandBuy'),('Creditcall'),('CyberSource'),('DataCash'),('DigiCash'),('Digital River'),('Dwolla'),('ecoPayz'),('Edy'),('Elavon'),('Euronet Worldwide'),('eWAY'),('Flooz'),('Fortumo'),('Google'),('GoCardless'),('Heartland Payment Systems'),('HSBC'),('iKobo'),('iZettle'),('IP Payments'),('Klarna'),('Live Gamer'),('Mobilpenge'),('ModusLink'),('MPP Global Solutions'),('Neteller'),('Nochex'),('Ogone'),('Paymate'),('PayPal'),('Payoneer'),('PayPoint'),('Paysafecard'),('PayXpert'),('Payza'),('Peppercoin'),('Playspan'),('Popmoney'),('Realex Payments'),('Recurly'),('RBK Money'),('Sage Group'),('Serve'),('Skrill (Moneybookers)'),('Stripe'),('Square, Inc.'),('TFI Markets'),('TIMWE'),('Use My Services (UMS)'),('Ukash'),('V.me by Visa'),('VeriFone'),('Vindicia'),('WebMoney'),('WePay'),('Wirecard'),('Western Union'),('WorldPay'),('Yandex money'),('Qiwi'),('OK Pay'),('Bitcoin'),('Perfect Money')")
			if err != nil {
				log.Error("%v", utils.ErrInfo(err))
				panic(err)
				os.Exit(1)
			}
		}
		count, err = c.Single(`SELECT count(*) FROM my_notifications`).Int64()
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			panic(err)
			os.Exit(1)
		}
		if count == 0 {
			err = c.DCDB.ExecSql(`INSERT INTO my_notifications (name, email, sms, mobile) VALUES ('admin_messages',1,1,1),('change_in_status',1,0,0),('dc_came_from',1,0,1),('dc_sent',1,0,0),('incoming_cash_requests',1,1,1),('new_version',1,1,1),('node_time',0,0,0),('system_error',1,1,0),('update_email',1,0,0),('update_primary_key',1,0,0),('update_sms_request',1,0,0),('voting_results',1,0,0),('voting_time',1,0,0)`)
			if err != nil {
				log.Error("%v", utils.ErrInfo(err))
				panic(err)
				os.Exit(1)
			}
		}

		err = c.DCDB.ExecSql(`INSERT INTO cf_lang (id, name) VALUES
		(1, 'English (US)'),
		(2, 'Afrikaans'),
		(3, 'Kiswahili'),
		(4, 'Türkçe'),
		(5, '‏עברית‏'),
		(6, '‏العربية‏'),
		(7, 'Español'),
		(8, 'Français (Canada)'),
		(9, 'Guarani'),
		(10, 'Português (Brasil)'),
		(11, 'Azərbaycan dili'),
		(12, 'Bahasa Indonesia'),
		(13, 'Bahasa Melayu'),
		(14, 'Basa Jawa'),
		(15, 'Bisaya'),
		(16, 'Filipino'),
		(17, 'Tiếng Việt'),
		(18, 'Հայերեն'),
		(19, '‏اردو‏'),
		(20, 'हिन्दी'),
		(21, 'বাংলা'),
		(22, 'ਪੰਜਾਬੀ'),
		(23, 'தமிழ்'),
		(24, 'తెలుగు'),
		(25, 'ಕನ್ನಡ'),
		(26, 'മലയാളം'),
		(27, 'සිංහල'),
		(28, 'ภาษาไทย'),
		(29, '한국어'),
		(30, '中文(台灣)'),
		(31, '中文(简体)'),
		(32, '中文(香港)'),
		(33, '日本語'),
		(35, 'Čeština'),
		(36, 'Magyar'),
		(37, 'Polski'),
		(38, 'Română'),
		(39, 'Slovenčina'),
		(40, 'Slovenščina'),
		(41, 'Български'),
		(42, 'Русский'),
		(43, 'Українська'),
		(45, 'Bosanski'),
		(46, 'Català'),
		(47, 'Cymraeg'),
		(48, 'Dansk'),
		(49, 'Deutsch'),
		(50, 'Eesti'),
		(51, 'English (UK)'),
		(52, 'Español (España)'),
		(53, 'Euskara'),
		(54, 'Français (France)'),
		(55, 'Galego'),
		(56, 'Hrvatski'),
		(57, 'Italiano'),
		(58, 'Latviešu'),
		(59, 'Lietuvių'),
		(60, 'Nederlands'),
		(61, 'Norsk (bokmål)'),
		(62, 'Português (Portugal)'),
		(63, 'Shqip'),
		(64, 'Suomi'),
		(65, 'Svenska'),
		(66, 'Ελληνικά'),
		(67, 'Македонски'),
		(68, 'Српски');`)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			panic(err)
			os.Exit(1)
		}

		err = c.DCDB.ExecSql(`INSERT INTO install (progress) VALUES ('complete')`)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			panic(err)
			os.Exit(1)
		}

	}()

	utils.Sleep(3) // даем время обновиться config.ini, чтобы в content выдался не installStep0, а updatingBlockchain
	TemplateStr, err := makeTemplate("install_step_1", "installStep1", &installStep1Struct{
		Lang: c.Lang})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
コード例 #10
0
ファイル: upgrade_6.go プロジェクト: dzyk/dcoin-go
func (c *Controller) Upgrade6() (string, error) {

	log.Debug("Upgrade6")

	var hostType string

	hostData, err := c.OneRow("SELECT http_host, tcp_host FROM " + c.MyPrefix + "my_table").String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// в режиме пула выдаем только хост ноды
	log.Debug("c.Community: %v", c.Community)
	log.Debug("c.PoolAdminUserId: %v", c.PoolAdminUserId)
	if c.Community /*&& len(data["http_host"]) == 0 && len(data["tcp_host"]) == 0*/ {
		hostType = "pool"
		hostData, err = c.OneRow("SELECT http_host, tcp_host FROM miners_data WHERE user_id  =  ?", c.PoolAdminUserId).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if len(hostData) == 0 {
			hostData["http_host"] = "null http_host in miners_data"
			hostData["tcp_host"] = "null tcp_host in miners_data"
		}
	} else {
		// если смогли подключиться из вне
		ip, err := utils.GetHttpTextAnswer("http://api.ipify.org")
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		/*httpHost, err := c.Single("SELECT http_host FROM "+c.MyPrefix+"my_table").String()
		if err!=nil {
			return "", utils.ErrInfo(err)
		}
		port := "8089"
		if len(httpHost) > 0 {
			re := regexp.MustCompile(`https?:\/\/(?:[0-9a-z\_\.\-]+):([0-9]+)`)
			match := re.FindStringSubmatch(httpHost)
			if len(match) != 0 {
				port = match[1];
			}
		}*/
		conn, err := net.DialTimeout("tcp", ip+":8089", 3*time.Second)
		log.Debug("ip: %v", ip)
		if err != nil {
			// если не смогли подключиться, то в JS будем искать рабочий пул и региться на нем. и дадим юзеру указать другие хост:ip
			hostType = "findPool"

		} else {
			hostType = "normal"
			defer conn.Close()
			hostData["http_host"] = ip + ":8089"
			hostData["tcp_host"] = ip + ":8088"
		}
	}

	// проверим, есть ли необработанные ключи в локальной табле
	nodePrivateKey, err := c.Single("SELECT private_key FROM " + c.MyPrefix + "my_node_keys WHERE block_id  =  0").String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	if len(nodePrivateKey) == 0 {
		//  сгенерим ключ для нода
		priv, pub := utils.GenKeys()
		err = c.ExecSql("INSERT INTO "+c.MyPrefix+"my_node_keys ( public_key, private_key ) VALUES ( [hex], ? )", pub, priv)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		nodePrivateKey = priv
	}

	var profileHash, faceHash, videoHash string

	if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg"); err == nil {
		file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg")
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		faceHash = string(utils.DSha256(file))
	}
	if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg"); err == nil {
		file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg")
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		profileHash = string(utils.DSha256(file))
	}

	if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_video.mp4"); err == nil {
		file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_video.mp4")
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		videoHash = string(utils.DSha256(file))
	}

	text, err := utils.GetHttpTextAnswer("http://dcoin.club/pools")
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	var pools_ []string
	err = json.Unmarshal([]byte(text), &pools_)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	log.Debug("pools: %v", pools_)
	rows, err := c.Query(c.FormatQuery(`
			SELECT user_id, http_host
			FROM miners_data
			WHERE user_id IN (` + strings.Join(pools_, ",") + `)`))
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	pools := make(map[string]string)
	for rows.Next() {
		var user_id, http_host string
		err = rows.Scan(&user_id, &http_host)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		pools[user_id] = http_host
	}
	poolsJs := ""
	for userId, httpHost := range pools {
		poolsJs = poolsJs + "[" + userId + ",'" + httpHost + "'],"
	}
	poolsJs = poolsJs[:len(poolsJs)-1]

	videoUrlId, err := c.Single("SELECT video_url_id FROM " + c.MyPrefix + "my_table").String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	saveAndGotoStep := strings.Replace(c.Lang["save_and_goto_step"], "[num]", "8", -1)
	upgradeMenu := utils.MakeUpgradeMenu(6)

	TemplateStr, err := makeTemplate("upgrade_6", "upgrade6", &upgrade6Page{
		Alert:           c.Alert,
		Lang:            c.Lang,
		SaveAndGotoStep: saveAndGotoStep,
		UpgradeMenu:     upgradeMenu,
		ShowSignData:    c.ShowSignData,
		SignData:        "",
		CountSignArr:    c.CountSignArr,
		HttpHost:        hostData["http_host"],
		TcpHost:         hostData["tcp_host"],
		Community:       c.Community,
		HostType:        hostType,
		ProfileHash:     profileHash,
		FaceHash:        faceHash,
		VideoHash:       videoHash,
		NodePrivateKey:  nodePrivateKey,
		Pools:           template.JS(poolsJs),
		UserId:          c.SessUserId,
		VideoUrlId:      videoUrlId,
		Mobile:          utils.Mobile()})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
コード例 #11
0
ファイル: type12.go プロジェクト: dzyk/dcoin-go
func (t *TcpServer) Type12() {

	/* Получаем данные от send_promised_amount_to_pool */
	log.Debug("Type12")
	// размер данных
	buf := make([]byte, 4)
	_, err := t.Conn.Read(buf)
	if err != nil {
		log.Error("%v", utils.ErrInfo(err))
		return
	}
	size := utils.BinToDec(buf)
	log.Debug("size: %d", size)
	if size < 32<<20 {
		// сами данные
		log.Debug("read data")
		binaryData := make([]byte, size)
		_, err = io.ReadFull(t.Conn, binaryData)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			return
		}
		//log.Debug("binaryData %x", binaryData)
		userId := utils.BinToDec(utils.BytesShift(&binaryData, 5))
		currencyId := utils.BinToDec(utils.BytesShift(&binaryData, 1))
		log.Debug("userId %d", userId)
		log.Debug("currencyId %d", currencyId)
		// проверим, есть ли такой юзер на пуле
		inPool, err := t.Single(`SELECT user_id FROM community WHERE user_id=?`, userId).Int64()
		if inPool <= 0 {
			log.Error("%v", utils.ErrInfo("inPool<=0"))
			_, err = t.Conn.Write(utils.DecToBin(0, 1))
			return
		}
		log.Debug("inPool %d", inPool)
		filesSign := utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData))
		log.Debug("filesSign %x", filesSign)
		size := utils.DecodeLength(&binaryData)
		log.Debug("size %d", size)
		data := utils.BytesShift(&binaryData, size)
		//log.Debug("data %x", data)
		fileType := utils.BinToDec(utils.BytesShift(&data, 1))
		log.Debug("fileType %d", fileType)
		fileName := utils.Int64ToStr(userId) + "_promised_amount_" + utils.Int64ToStr(currencyId) + ".mp4"
		forSign := string(utils.DSha256((data)))
		log.Debug("forSign %s", forSign)
		err = ioutil.WriteFile(os.TempDir()+"/"+fileName, data, 0644)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			return
		}

		if len(forSign) == 0 {
			log.Error("%v", utils.ErrInfo("len(forSign) == 0"))
			_, err = t.Conn.Write(utils.DecToBin(0, 1))
			return
		}
		// проверим подпись
		publicKey, err := t.GetUserPublicKey(userId)
		resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin(filesSign), true)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			_, err = t.Conn.Write(utils.DecToBin(0, 1))
			return
		}
		if resultCheckSign {
			utils.CopyFileContents(os.TempDir()+"/"+fileName, *utils.Dir+"/public/"+fileName)
		} else {
			os.Remove(os.TempDir() + "/" + fileName)
		}

		// и возвращаем статус
		_, err = t.Conn.Write(utils.DecToBin(1, 1))
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			return
		}
	} else {
		log.Error("%v", utils.ErrInfo("size>32mb"))
	}
}
コード例 #12
0
ファイル: cash_request_out.go プロジェクト: dzyk/dcoin-go
func (c *Controller) CashRequestOut() (string, error) {

	txType := "CashRequestOut"
	txTypeId := utils.TypeInt(txType)
	timeNow := utils.Time()

	cashRequestsStatus := map[string]string{"my_pending": c.Lang["local_pending"], "pending": c.Lang["pending"], "approved": c.Lang["approved"], "rejected": c.Lang["rejected"]}

	jsonCurrencyWallets := ""
	var availableCurrency []int64
	// список отравленных нами запросов
	myCashRequests, err := c.GetAll("SELECT * FROM "+c.MyPrefix+"my_cash_requests WHERE to_user_id != ?", -1, c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	// получаем список кошельков, на которых есть FC
	rows, err := c.Query(c.FormatQuery("SELECT amount, currency_id, last_update FROM wallets WHERE user_id = ? AND currency_id < 1000"), c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		var amount float64
		var currency_id, last_update int64
		err = rows.Scan(&amount, &currency_id, &last_update)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if currency_id == 1 {
			continue
		}
		profit, err := c.CalcProfitGen(currency_id, amount, c.SessUserId, last_update, timeNow, "wallets")
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		amount += profit
		jsonCurrencyWallets += fmt.Sprintf(`"%d":["%s","%v"],`, currency_id, c.CurrencyList[currency_id], amount)
		availableCurrency = append(availableCurrency, currency_id)
	}
	jsonCurrencyWallets = jsonCurrencyWallets[:len(jsonCurrencyWallets)-1]
	//jsonCurrencyWallets = "\""
	log.Debug("jsonCurrencyWallets", jsonCurrencyWallets)
	code := utils.Md5(utils.RandSeq(50))
	hashCode := utils.DSha256(code)

	TemplateStr, err := makeTemplate("cash_request_out", "cashRequestOut", &cashRequestOutPage{
		Alert:               c.Alert,
		Lang:                c.Lang,
		CountSignArr:        c.CountSignArr,
		ShowSignData:        c.ShowSignData,
		UserId:              c.SessUserId,
		TimeNow:             timeNow,
		TxType:              txType,
		TxTypeId:            txTypeId,
		SignData:            "",
		CurrencyList:        c.CurrencyList,
		PaymentSystems:      c.PaymentSystems,
		JsonCurrencyWallets: jsonCurrencyWallets,
		CashRequestsStatus:  cashRequestsStatus,
		AvailableCurrency:   availableCurrency,
		MinPromisedAmount:   c.Variables.Int64["min_promised_amount"],
		MyCashRequests:      myCashRequests,
		Code:                string(code),
		HashCode:            string(hashCode),
		MaxLength:           200})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
コード例 #13
0
ファイル: check_sign.go プロジェクト: dzyk/dcoin-go
func (c *Controller) Check_sign() (string, error) {

	var checkError bool

	c.r.ParseForm()
	n := []byte(c.r.FormValue("n"))
	e := []byte(c.r.FormValue("e"))
	sign := []byte(c.r.FormValue("sign"))
	setupPassword := c.r.FormValue("setup_password")
	private_key := c.r.FormValue("private_key")
	if !utils.CheckInputData(n, "hex") {
		return `{"result":"incorrect n"}`, nil
	}
	if !utils.CheckInputData(e, "hex") {
		return `{"result":"incorrect e"}`, nil
	}
	if !utils.CheckInputData(string(sign), "hex_sign") {
		return `{"result":"incorrect sign"}`, nil
	}

	allTables, err := c.DCDB.GetAllTables()
	if err != nil {
		return "{\"result\":0}", err
	}

	var hash []byte
	log.Debug("configIni[sign_hash] %s", configIni["sign_hash"])
	log.Debug("c.r.RemoteAddr %s", c.r.RemoteAddr)
	log.Debug("c.r.Header.Get(User-Agent) %s", c.r.Header.Get("User-Agent"))
	RemoteAddr := utils.RemoteAddrFix(c.r.RemoteAddr)
	re := regexp.MustCompile(`(.*?):[0-9]+$`)
	match := re.FindStringSubmatch(RemoteAddr)
	if len(match) != 0 {
		RemoteAddr = match[1]
	}
	log.Debug("RemoteAddr %s", RemoteAddr)
	hash = utils.Md5(c.r.Header.Get("User-Agent") + RemoteAddr)
	log.Debug("hash %s", hash)

	if len(c.CommunityUsers) > 0 {

		// в цикле проверяем, кому подойдет присланная подпись
		for _, userId := range c.CommunityUsers {

			myPrefix := utils.Int64ToStr(userId) + "_"
			if !utils.InSliceString(myPrefix+"my_keys", allTables) {
				continue
			}

			// получим открытый ключ юзера
			publicKey, err := c.DCDB.GetMyPublicKey(myPrefix)
			if err != nil {
				return "{\"result\":0}", err
			}

			// получим данные для подписи
			forSign, err := c.DCDB.GetDataAuthorization(hash)

			log.Debug("publicKey: %x\n", publicKey)
			log.Debug("myPrefix: ", myPrefix)
			log.Debug("sign:  %s\n", sign)
			log.Debug("hash: %s\n", hash)
			log.Debug("forSign: ", forSign)
			// проверим подпись
			resultCheckSign, err := utils.CheckSign([][]byte{publicKey}, forSign, utils.HexToBin(sign), true)
			if err != nil {
				continue
			}
			// если подпись верная, значит мы нашли юзера, который эту подпись смог сделать
			if resultCheckSign {
				myUserId := userId
				// убираем ограниченный режим
				c.sess.Delete("restricted")
				c.sess.Set("user_id", myUserId)
				log.Debug("c.sess.Set(user_id) %d", myUserId)
				public_key, err := c.DCDB.GetUserPublicKey(myUserId)
				if err != nil {
					return "{\"result\":0}", err
				}
				// паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился
				c.sess.Set("public_key", string(utils.BinToHex([]byte(public_key))))
				log.Debug("string(utils.BinToHex([]byte(public_key))) %s", string(utils.BinToHex([]byte(public_key))))

				adminUSerID, err := c.DCDB.GetAdminUserId()
				if err != nil {
					return "{\"result\":0}", err
				}
				if adminUSerID == myUserId {
					c.sess.Set("admin", 1)
				}
				return "{\"result\":1}", nil
			}
		}
		log.Debug("restricted test")
		// если дошли досюда, значит ни один ключ не подошел и даем возможность войти в ограниченном режиме
		publicKey := utils.MakeAsn1(n, e)
		userId_, err := c.DCDB.GetUserIdByPublicKey(publicKey)
		userId := utils.StrToInt64(userId_)
		if err != nil {
			return "{\"result\":0}", err
		}

		log.Debug("userId:", userId)
		// юзер с таким ключем есть в БД
		if userId > 0 {

			// получим данные для подписи
			forSign, err := c.DCDB.GetDataAuthorization(hash)
			log.Debug("forSign", forSign)
			log.Debug("publicKey %x\n", utils.HexToBin(publicKey))
			log.Debug("sign_", string(sign))
			// проверим подпись
			resultCheckSign, err := utils.CheckSign([][]byte{utils.HexToBin(publicKey)}, forSign, utils.HexToBin(sign), true)
			if err != nil {
				return "{\"result\":0}", err
			}
			if resultCheckSign {

				// если юзер смог подписать наш хэш, значит у него актуальный праймари ключ
				c.sess.Set("user_id", userId)
				log.Debug("c.sess.Set(user_id) %d", userId)

				// паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился
				c.sess.Set("public_key", string(publicKey))

				// возможно в табле my_keys старые данные, но если эта табла есть, то нужно добавить туда ключ
				if utils.InSliceString(utils.Int64ToStr(userId)+"_my_keys", allTables) {
					curBlockId, err := c.DCDB.GetBlockId()
					if err != nil {
						return "{\"result\":0}", err
					}
					err = c.DCDB.InsertIntoMyKey(utils.Int64ToStr(userId)+"_", publicKey, utils.Int64ToStr(curBlockId))
					if err != nil {
						return "{\"result\":0}", err
					}
					c.sess.Delete("restricted")
				} else {
					c.sess.Set("restricted", int64(1))
					log.Debug("c.sess.Set(restricted) 1")
				}
				return "{\"result\":1}", nil
			} else {
				return "{\"result\":0}", nil
			}
		}
	} else {
		// получим открытый ключ юзера
		publicKey, err := c.DCDB.GetMyPublicKey("")
		if err != nil {
			return "{\"result\":0}", err
		}

		// Если ключ еще не успели установить
		if len(publicKey) == 0 {

			// пока не собрана цепочка блоков не даем ввести ключ
			infoBlock, err := c.DCDB.GetInfoBlock()
			if err != nil {
				return "{\"result\":0}", err
			}
			// если последний блок не старше 2-х часов
			wTime := int64(2)
			if c.ConfigIni["test_mode"] == "1" {
				wTime = 2 * 365 * 24
			}
			log.Debug("%v/%v/%v", time.Now().Unix(), utils.StrToInt64(infoBlock["time"]), wTime)
			if (time.Now().Unix() - utils.StrToInt64(infoBlock["time"])) < 3600*wTime {

				// проверим, верный ли установочный пароль, если он, конечно, есть
				setupPassword_, err := c.Single("SELECT setup_password FROM config").String()
				if err != nil {
					return "{\"result\":0}", err
				}
				if len(setupPassword_) > 0 && setupPassword_ != string(utils.DSha256(setupPassword)) {
					log.Debug(setupPassword_, string(utils.DSha256(setupPassword)), setupPassword)
					return "{\"result\":0}", nil
				}

				publicKey := utils.MakeAsn1(n, e)
				log.Debug("new key", string(publicKey))
				userId, err := c.GetUserIdByPublicKey(publicKey)
				if err != nil {
					return "{\"result\":0}", err
				}

				// получим данные для подписи
				forSign, err := c.DCDB.GetDataAuthorization(hash)
				if err != nil {
					return "{\"result\":0}", err
				}
				log.Debug("forSign", forSign)
				log.Debug("publicKey %x\n", utils.HexToBin(publicKey))
				log.Debug("sign_", string(sign))
				// проверим подпись
				resultCheckSign, err := utils.CheckSign([][]byte{utils.HexToBin(publicKey)}, forSign, utils.HexToBin(sign), true)
				if err != nil {
					return "{\"result\":0}", err
				}
				if !resultCheckSign {
					return "{\"result\":0}", nil
				}

				if len(userId) > 0 {
					err := c.InsertIntoMyKey("", publicKey, "0")
					if err != nil {
						return "{\"result\":0}", err
					}
					minerId, err := c.GetMinerId(utils.StrToInt64(userId))
					if err != nil {
						return "{\"result\":0}", err
					}
					//myUserId, err := c.GetMyUserId("")
					//if myUserId > 0 {
					if minerId > 0 {
						err = c.ExecSql("UPDATE my_table SET user_id = ?, miner_id = ?, status = 'miner'", userId, minerId)
						if err != nil {
							return "{\"result\":0}", err
						}
					} else {
						err = c.ExecSql("UPDATE my_table SET user_id = ?, status = 'user'", userId)
						if err != nil {
							return "{\"result\":0}", err
						}
					}
					//} else {
					//	c.ExecSql("INSERT INTO my_table (user_id, status) VALUES (?, 'user')", userId)
					//}
					// возможно юзер хочет сохранить свой ключ
					if len(private_key) > 0 {
						c.ExecSql("UPDATE my_keys SET private_key = ? WHERE block_id = (SELECT max(block_id) FROM my_keys)", private_key)
					}

				} else {
					checkError = true
				}
			} else {
				checkError = true
			}
		} else {

			log.Debug("RemoteAddr %s", RemoteAddr)
			hash = utils.Md5(c.r.Header.Get("User-Agent") + RemoteAddr)
			log.Debug("hash %s", hash)

			// получим данные для подписи
			forSign, err := c.DCDB.GetDataAuthorization(hash)
			log.Debug("forSign", forSign)
			log.Debug("publicKey %x\n", string(publicKey))
			log.Debug("sign_", string(sign))
			// проверим подпись
			resultCheckSign, err := utils.CheckSign([][]byte{publicKey}, forSign, utils.HexToBin(sign), true)
			if err != nil {
				return "{\"result\":0}", err
			}
			if !resultCheckSign {
				return "{\"result\":0}", nil
			}

		}

		if checkError {
			return "{\"result\":0}", nil
		} else {
			myUserId, err := c.DCDB.GetMyUserId("")
			if myUserId == 0 {
				myUserId = -1
			}
			if err != nil {
				return "{\"result\":0}", err
			}
			c.sess.Delete("restricted")
			c.sess.Set("user_id", myUserId)

			// если уже пришел блок, в котором зареган ключ юзера
			if myUserId != -1 {

				public_key, err := c.DCDB.GetUserPublicKey(myUserId)
				if err != nil {
					return "{\"result\":0}", err
				}
				// паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился
				c.sess.Set("public_key", string(utils.BinToHex(public_key)))

				// возможно юзер хочет сохранить свой ключ
				if len(private_key) > 0 {
					c.ExecSql("UPDATE my_keys SET private_key = ? WHERE block_id = (SELECT max(block_id) FROM my_keys)", private_key)
				}

				AdminUserId, err := c.DCDB.GetAdminUserId()
				if err != nil {
					return "{\"result\":0}", err
				}
				if AdminUserId == myUserId {
					c.sess.Set("admin", int64(1))
				}
				return "{\"result\":1}", nil
			}
		}
	}
	return "{\"result\":0}", nil
}
コード例 #14
0
func (c *Controller) GenerateNewPrimaryKey() (string, error) {

	c.r.ParseForm()
	password := c.r.FormValue("password")

	priv, pub := utils.GenKeys()
	if len(password) > 0 {
		log.Debug("priv:", priv)
		encKey, err := utils.Encrypt(utils.Md5("11"), []byte(priv))
		log.Debug("priv encKey:", encKey)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		priv = base64.StdEncoding.EncodeToString(encKey)
		log.Debug("priv ENC:", priv)
		//priv = string(encKey)
	}
	json, err := json.Marshal(map[string]string{"private_key": priv, "public_key": pub, "password_hash": string(utils.DSha256(password))})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	log.Debug("%v", json)
	return string(json), nil
}
コード例 #15
0
ファイル: upgrade_7.go プロジェクト: dzyk/dcoin-go
func (c *Controller) Upgrade7() (string, error) {

	log.Debug("Upgrade7")

	txType := "NewMiner"
	txTypeId := utils.TypeInt(txType)
	timeNow := utils.Time()

	// Формируем контент для подписи
	myTable, err := c.OneRow("SELECT user_id, race, country, geolocation, http_host, tcp_host, face_coords, profile_coords, video_url_id, video_type FROM " + c.MyPrefix + "my_table").String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	if len(myTable["video_url_id"]) == 0 {
		myTable["video_url_id"] = "null"
	}
	if len(myTable["video_type"]) == 0 {
		myTable["video_type"] = "null"
	}
	var profileHash, faceHash string

	if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg"); err == nil {
		file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg")
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		faceHash = string(utils.DSha256(file))
	}
	if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg"); err == nil {
		file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg")
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		profileHash = string(utils.DSha256(file))
	}

	latitude := "0"
	longitude := "0"
	if len(myTable["geolocation"]) > 0 {
		x := strings.Split(myTable["geolocation"], ", ")
		latitude = x[0]
		longitude = x[1]
	}

	// проверим, есть ли не обработанные ключи в локальной табле
	nodePublicKey, err := c.Single("SELECT public_key FROM " + c.MyPrefix + "my_node_keys WHERE block_id  =  0").String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	if len(nodePublicKey) == 0 {
		//  сгенерим ключ для нода
		priv, pub := utils.GenKeys()
		err = c.ExecSql("INSERT INTO "+c.MyPrefix+"my_node_keys ( public_key, private_key ) VALUES ( [hex], ? )", pub, priv)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
	} else {
		nodePublicKey = string(utils.BinToHex([]byte(nodePublicKey)))
	}

	saveAndGotoStep := strings.Replace(c.Lang["save_and_goto_step"], "[num]", "9", -1)
	upgradeMenu := utils.MakeUpgradeMenu(7)

	var noExistsMp4 bool
	if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_video.mp4"); os.IsNotExist(err) {
		noExistsMp4 = true
	}

	TemplateStr, err := makeTemplate("upgrade_7", "upgrade7", &upgrade7Page{
		Alert:           c.Alert,
		Lang:            c.Lang,
		CountSignArr:    c.CountSignArr,
		ShowSignData:    c.ShowSignData,
		UserId:          c.SessUserId,
		TimeNow:         timeNow,
		TxType:          txType,
		TxTypeId:        txTypeId,
		NoExistsMp4:     noExistsMp4,
		SignData:        fmt.Sprintf("%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v", txTypeId, timeNow, c.SessUserId, myTable["race"], myTable["country"], latitude, longitude, myTable["http_host"], myTable["tcp_host"], faceHash, profileHash, myTable["face_coords"], myTable["profile_coords"], myTable["video_type"], myTable["video_url_id"], nodePublicKey),
		SaveAndGotoStep: saveAndGotoStep,
		UpgradeMenu:     upgradeMenu,
		Latitude:        latitude,
		Longitude:       longitude,
		NodePublicKey:   nodePublicKey,
		ProfileHash:     profileHash,
		FaceHash:        faceHash,
		Data:            myTable,
		MyTable:         myTable,
		Mobile:          utils.Mobile()})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
コード例 #16
0
ファイル: type6.go プロジェクト: dzyk/dcoin-go
func (t *TcpServer) Type6() {
	/**
	- проверяем, находится ли отправитель на одном с нами уровне
	- получаем  block_id, user_id, mrkl_root, signature
	- если хэш блока меньше того, что есть у нас в табле testblock, то смотртим, есть ли такой же хэш тр-ий,
	- если отличается, то загружаем блок от отправителя
	- если не отличается, то просто обновляем хэш блока у себя
	данные присылает демон testblockDisseminator
	*/
	currentBlockId, err := t.GetBlockId()
	if err != nil {
		log.Error("%v", utils.ErrInfo(err))
		return
	}
	if currentBlockId == 0 {
		log.Debug("%v", utils.ErrInfo("currentBlockId == 0"))
		return
	}
	buf := make([]byte, 4)
	_, err = t.Conn.Read(buf)
	if err != nil {
		log.Error("%v", utils.ErrInfo(err))
		return
	}
	size := utils.BinToDec(buf)
	log.Debug("size: %v", size)
	if size < 10485760 {
		binaryData := make([]byte, size)
		//binaryData, err = ioutil.ReadAll(t.Conn)
		_, err = io.ReadFull(t.Conn, binaryData)
		if err != nil {
			log.Error("%v", utils.ErrInfo(err))
			return
		}
		log.Debug("binaryData: %x", binaryData)
		newTestblockBlockId := utils.BinToDecBytesShift(&binaryData, 4)
		newTestblockTime := utils.BinToDecBytesShift(&binaryData, 4)
		newTestblockUserId := utils.BinToDecBytesShift(&binaryData, 4)
		newTestblockMrklRoot := utils.BinToHex(utils.BytesShift(&binaryData, 32))
		newTestblockSignatureHex := utils.BinToHex(utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData)))
		log.Debug("newTestblockBlockId: %v", newTestblockBlockId)
		log.Debug("newTestblockTime: %v", newTestblockTime)
		log.Debug("newTestblockUserId: %v", newTestblockUserId)
		log.Debug("newTestblockMrklRoot: %s", newTestblockMrklRoot)
		log.Debug("newTestblockSignatureHex: %s", newTestblockSignatureHex)
		if !utils.CheckInputData(newTestblockBlockId, "int") {
			log.Debug("%v", utils.ErrInfo("incorrect newTestblockBlockId"))
			return
		}
		if !utils.CheckInputData(newTestblockTime, "int") {
			log.Debug("%v", utils.ErrInfo("incorrect newTestblockTime"))
			return
		}
		if !utils.CheckInputData(newTestblockUserId, "int") {
			log.Debug("%v", utils.ErrInfo("incorrect newTestblockUserId"))
			return
		}
		if !utils.CheckInputData(newTestblockMrklRoot, "sha256") {
			log.Debug("%v", utils.ErrInfo("incorrect newTestblockMrklRoot"))
			return
		}
		/*
		 * Проблема одновременных попыток локнуть. Надо попробовать без локов
		 * */
		//t.DbLockGate("6")
		exists, err := t.Single(`
				SELECT block_id
				FROM testblock
				WHERE status = 'active'
				`).Int64()
		if err != nil {
			t.PrintSleep(utils.ErrInfo(err), 0)
			return
		}
		if exists == 0 {
			t.PrintSleep(utils.ErrInfo("null testblock"), 0)
			return
		}
		//prevBlock, myUserId, myMinerId, currentUserId, level, levelsRange, err := t.TestBlock()
		prevBlock, _, _, _, level, levelsRange, err := t.TestBlock()
		if err != nil {
			t.PrintSleep(utils.ErrInfo(err), 0)
			return
		}
		nodesIds := utils.GetOurLevelNodes(level, levelsRange)
		log.Debug("nodesIds: %v ", nodesIds)
		log.Debug("prevBlock: %v ", prevBlock)
		log.Debug("level: %v ", level)
		log.Debug("levelsRange: %v ", levelsRange)
		log.Debug("newTestblockBlockId: %v ", newTestblockBlockId)
		// проверим, верный ли ID блока
		if newTestblockBlockId != prevBlock.BlockId+1 {
			t.PrintSleep(utils.ErrInfo(fmt.Sprintf("newTestblockBlockId != prevBlock.BlockId+1 %d!=%d+1", newTestblockBlockId, prevBlock.BlockId)), 1)
			return
		}
		// проверим, есть ли такой майнер
		minerId, err := t.Single("SELECT miner_id FROM miners_data WHERE user_id  =  ?", newTestblockUserId).Int64()
		if err != nil {
			t.PrintSleep(utils.ErrInfo(err), 0)
			return
		}
		if minerId == 0 {
			t.PrintSleep(utils.ErrInfo("minerId == 0"), 0)
			return
		}
		log.Debug("minerId: %v ", minerId)
		// проверим, точно ли отправитель с нашего уровня
		if !utils.InSliceInt64(minerId, nodesIds) {
			t.PrintSleep(utils.ErrInfo("!InSliceInt64(minerId, nodesIds)"), 0)
			return
		}
		// допустимая погрешность во времени генерации блока
		maxErrorTime := t.variables.Int64["error_time"]
		// получим значения для сна
		sleep, err := t.GetGenSleep(prevBlock, level)
		if err != nil {
			t.PrintSleep(utils.ErrInfo(err), 0)
			return
		}
		// исключим тех, кто сгенерил блок слишком рано
		if prevBlock.Time+sleep-newTestblockTime > maxErrorTime {
			t.PrintSleep(utils.ErrInfo("prevBlock.Time + sleep - newTestblockTime > maxErrorTime"), 0)
			return
		}
		// исключим тех, кто сгенерил блок с бегущими часами
		if newTestblockTime > utils.Time() {
			t.PrintSleep(utils.ErrInfo("newTestblockTime > Time()"), 0)
			return
		}
		// получим хэш заголовка
		newHeaderHash := utils.DSha256(fmt.Sprintf("%v,%v,%v", newTestblockUserId, newTestblockBlockId, prevBlock.HeadHash))
		myTestblock, err := t.OneRow(`
				SELECT block_id,
							user_id,
							hex(mrkl_root) as mrkl_root,
							hex(signature) as signature
				FROM testblock
				WHERE status = 'active'
				`).String()
		if len(myTestblock) > 0 {
			if err != nil {
				t.PrintSleep(utils.ErrInfo(err), 0)
				return
			}
			// получим хэш заголовка
			myHeaderHash := utils.DSha256(fmt.Sprintf("%v,%v,%v", myTestblock["user_id"], myTestblock["block_id"], prevBlock.HeadHash))
			// у кого меньше хэш, тот и круче
			hash1 := big.NewInt(0)
			hash1.SetString(string(newHeaderHash), 16)
			hash2 := big.NewInt(0)
			hash2.SetString(string(myHeaderHash), 16)
			log.Debug("%v", hash1.Cmp(hash2))
			//if HexToDecBig(newHeaderHash) > string(myHeaderHash) {
			if hash1.Cmp(hash2) == 1 {
				t.PrintSleep(utils.ErrInfo(fmt.Sprintf("newHeaderHash > myHeaderHash (%s > %s)", newHeaderHash, myHeaderHash)), 0)
				return
			}
			/* т.к. на данном этапе в большинстве случаев наш текущий блок будет заменен,
			 * то нужно парсить его, рассылать другим нодам и дождаться окончания проверки
			 */
			err = t.ExecSql("UPDATE testblock SET status = 'pending'")
			if err != nil {
				t.PrintSleep(utils.ErrInfo(err), 0)
				return
			}
		}
		// если отличается, то загружаем недостающии тр-ии от отправителя
		if string(newTestblockMrklRoot) != myTestblock["mrkl_root"] {
			log.Debug("download new tx")
			sendData := ""
			// получим все имеющиеся у нас тр-ии, которые еще не попали в блоки
			txArray, err := t.GetMap(`SELECT hex(hash) as hash, data FROM transactions`, "hash", "data")
			if err != nil {
				t.PrintSleep(utils.ErrInfo(err), 0)
				return
			}
			for hash, _ := range txArray {
				sendData += hash
			}
			err = utils.WriteSizeAndData([]byte(sendData), t.Conn)
			if err != nil {
				t.PrintSleep(utils.ErrInfo(err), 0)
				return
			}
			/*
				в ответ получаем:
				BLOCK_ID   				       4
				TIME       					       4
				USER_ID                         5
				SIGN                               от 128 до 512 байт. Подпись от TYPE, BLOCK_ID, PREV_BLOCK_HASH, TIME, USER_ID, LEVEL, MRKL_ROOT
				Размер всех тр-ий, размер 1 тр-ии, тело тр-ии.
				Хэши три-ий (порядок тр-ий)
			*/
			buf := make([]byte, 4)
			_, err = t.Conn.Read(buf)
			if err != nil {
				t.PrintSleep(utils.ErrInfo(err), 0)
				return
			}
			dataSize := utils.BinToDec(buf)
			log.Debug("dataSize %d", dataSize)
			// и если данных менее 10мб, то получаем их
			if dataSize < 10485760 {
				binaryData := make([]byte, dataSize)
				//binaryData, err = ioutil.ReadAll(t.Conn)
				_, err = io.ReadFull(t.Conn, binaryData)
				if err != nil {
					t.PrintSleep(utils.ErrInfo(err), 0)
					return
				}
				// Разбираем полученные бинарные данные
				newTestblockBlockId := utils.BinToDecBytesShift(&binaryData, 4)
				newTestblockTime := utils.BinToDecBytesShift(&binaryData, 4)
				newTestblockUserId := utils.BinToDecBytesShift(&binaryData, 5)
				newTestblockSignature := utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData))
				log.Debug("newTestblockBlockId %v", newTestblockBlockId)
				log.Debug("newTestblockTime %v", newTestblockTime)
				log.Debug("newTestblockUserId %v", newTestblockUserId)
				log.Debug("newTestblockSignature %x", newTestblockSignature)
				// недостающие тр-ии
				length := utils.DecodeLength(&binaryData) // размер всех тр-ий
				txBinary := utils.BytesShift(&binaryData, length)
				for {
					// берем по одной тр-ии
					length := utils.DecodeLength(&txBinary) // размер всех тр-ий
					if length == 0 {
						break
					}
					log.Debug("length %d", length)
					tx := utils.BytesShift(&txBinary, length)
					log.Debug("tx %x", tx)
					txArray[string(utils.Md5(tx))] = string(tx)
				}
				// порядок тр-ий
				var orderHashArray []string
				for {
					orderHashArray = append(orderHashArray, string(utils.BinToHex(utils.BytesShift(&binaryData, 16))))
					if len(binaryData) == 0 {
						break
					}
				}
				// сортируем и наши и полученные транзакции
				var transactions []byte
				for _, txMd5 := range orderHashArray {
					transactions = append(transactions, utils.EncodeLengthPlusData([]byte(txArray[txMd5]))...)
				}
				// формируем блок, который далее будем тщательно проверять
				/*
					Заголовок (от 143 до 527 байт )
					TYPE (0-блок, 1-тр-я)     1
					BLOCK_ID   				       4
					TIME       					       4
					USER_ID                         5
					LEVEL                              1
					SIGN                               от 128 до 512 байт. Подпись от TYPE, BLOCK_ID, PREV_BLOCK_HASH, TIME, USER_ID, LEVEL, MRKL_ROOT
					Далее - тело блока (Тр-ии)
				*/
				newBlockIdBinary := utils.DecToBin(newTestblockBlockId, 4)
				timeBinary := utils.DecToBin(newTestblockTime, 4)
				userIdBinary := utils.DecToBin(newTestblockUserId, 5)
				levelBinary := utils.DecToBin(level, 1)
				newBlockHeader := utils.DecToBin(0, 1) // 0 - это блок
				newBlockHeader = append(newBlockHeader, newBlockIdBinary...)
				newBlockHeader = append(newBlockHeader, timeBinary...)
				newBlockHeader = append(newBlockHeader, userIdBinary...)
				newBlockHeader = append(newBlockHeader, levelBinary...) // $level пишем, чтобы при расчете времени ожидания в следующем блоке не пришлось узнавать, какой был max_miner_id
				newBlockHeader = append(newBlockHeader, utils.EncodeLengthPlusData(newTestblockSignature)...)
				newBlockHex := utils.BinToHex(append(newBlockHeader, transactions...))
				// и передаем блок для обратотки через демон queue_parser_testblock
				// т.к. есть запросы к log_time_, а их можно выполнять только по очереди
				err = t.ExecSql(`DELETE FROM queue_testblock WHERE hex(head_hash) = ?`, newHeaderHash)
				if err != nil {
					t.PrintSleep(utils.ErrInfo(err), 0)
					return
				}
				log.Debug("INSERT INTO queue_testblock  (head_hash, data)  VALUES (%s, %s)", newHeaderHash, newBlockHex)
				err = t.ExecSql(`INSERT INTO queue_testblock (head_hash, data) VALUES ([hex], [hex])`, newHeaderHash, newBlockHex)
				if err != nil {
					t.PrintSleep(utils.ErrInfo(err), 0)
					return
				}
			}
		} else {
			// если всё нормально, то пишем в таблу testblock новые данные
			exists, err := t.Single(`SELECT block_id FROM testblock`).Int64()
			if err != nil {
				t.PrintSleep(utils.ErrInfo(err), 0)
				return
			}
			if exists == 0 {
				err = t.ExecSql(`INSERT INTO testblock (block_id, time, level, user_id, header_hash, signature, mrkl_root) VALUES (?, ?, ?, ?, [hex], [hex], [hex])`,
					newTestblockBlockId, newTestblockTime, level, newTestblockUserId, string(newHeaderHash), newTestblockSignatureHex, string(newTestblockMrklRoot))
				if err != nil {
					t.PrintSleep(utils.ErrInfo(err), 0)
					return
				}
			} else {
				err = t.ExecSql(`
						UPDATE testblock
						SET   time = ?,
								user_id = ?,
								header_hash = [hex],
								signature = [hex]
						`, newTestblockTime, newTestblockUserId, string(newHeaderHash), string(newTestblockSignatureHex))
				if err != nil {
					t.PrintSleep(utils.ErrInfo(err), 0)
					return
				}
			}
		}
		err = t.ExecSql("UPDATE testblock SET status = 'active'")
		if err != nil {
			t.PrintSleep(utils.ErrInfo(err), 0)
			return
		}
		//t.DbUnlockGate("6")
	}
}