You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.8 KiB
178 lines
4.8 KiB
/*
|
|
This file is part of cpp-ethereum.
|
|
|
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
cpp-ethereum is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
/** @file Whisper.cpp
|
|
* @author Gav Wood <i@gavwood.com>
|
|
* @date 2015
|
|
*/
|
|
|
|
#include "Whisper.h"
|
|
#include <QSettings>
|
|
#include <libethereum/Client.h>
|
|
#include <libethereum/Utility.h>
|
|
#include <libwhisper/WhisperHost.h>
|
|
#include <libweb3jsonrpc/WebThreeStubServerBase.h>
|
|
#include "OurWebThreeStubServer.h"
|
|
#include "ui_Whisper.h"
|
|
using namespace std;
|
|
using namespace dev;
|
|
using namespace az;
|
|
using namespace eth;
|
|
|
|
DEV_AZ_NOTE_PLUGIN(Whisper);
|
|
|
|
static Public stringToPublic(QString const& _a)
|
|
{
|
|
string sn = _a.toStdString();
|
|
if (_a.size() == sizeof(Public) * 2)
|
|
return Public(fromHex(_a.toStdString()));
|
|
else if (_a.size() == sizeof(Public) * 2 + 2 && _a.startsWith("0x"))
|
|
return Public(fromHex(_a.mid(2).toStdString()));
|
|
else
|
|
return Public();
|
|
}
|
|
|
|
static shh::Topics topicFromText(QString _s)
|
|
{
|
|
shh::BuildTopic ret;
|
|
while (_s.size())
|
|
{
|
|
QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?");
|
|
QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?");
|
|
QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?");
|
|
bytes part;
|
|
if (r.exactMatch(_s))
|
|
{
|
|
for (auto i: r.cap(2))
|
|
part.push_back((byte)i.toLatin1());
|
|
if (r.cap(1) != "$")
|
|
for (int i = r.cap(2).size(); i < 32; ++i)
|
|
part.push_back(0);
|
|
else
|
|
part.push_back(0);
|
|
_s = r.cap(3);
|
|
}
|
|
else if (d.exactMatch(_s))
|
|
{
|
|
u256 v(d.cap(2).toStdString());
|
|
if (d.cap(6) == "szabo")
|
|
v *= szabo;
|
|
else if (d.cap(5) == "finney")
|
|
v *= finney;
|
|
else if (d.cap(4) == "ether")
|
|
v *= ether;
|
|
bytes bs = dev::toCompactBigEndian(v);
|
|
if (d.cap(1) != "$")
|
|
for (auto i = bs.size(); i < 32; ++i)
|
|
part.push_back(0);
|
|
for (auto b: bs)
|
|
part.push_back(b);
|
|
_s = d.cap(7);
|
|
}
|
|
else if (h.exactMatch(_s))
|
|
{
|
|
bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString());
|
|
if (h.cap(1) != "$")
|
|
for (auto i = bs.size(); i < 32; ++i)
|
|
part.push_back(0);
|
|
for (auto b: bs)
|
|
part.push_back(b);
|
|
_s = h.cap(5);
|
|
}
|
|
else
|
|
_s = _s.mid(1);
|
|
ret.shift(part);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
Whisper::Whisper(MainFace* _m):
|
|
Plugin(_m, "Whisper"),
|
|
m_ui(new Ui::Whisper)
|
|
{
|
|
dock(Qt::RightDockWidgetArea, "Whisper")->setWidget(new QWidget);
|
|
m_ui->setupUi(dock()->widget());
|
|
connect(addMenuItem("New Whisper identity.", "menuNetwork", true), &QAction::triggered, this, &Whisper::on_newIdentity_triggered);
|
|
connect(_m->web3Server(), &OurWebThreeStubServer::onNewId, this, &Whisper::addNewId);
|
|
}
|
|
|
|
void Whisper::readSettings(QSettings const& _s)
|
|
{
|
|
m_myIdentities.clear();
|
|
QByteArray b = _s.value("identities").toByteArray();
|
|
if (!b.isEmpty())
|
|
{
|
|
Secret k;
|
|
for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
|
|
{
|
|
memcpy(k.writable().data(), b.data() + i * sizeof(Secret), sizeof(Secret));
|
|
if (!count(m_myIdentities.begin(), m_myIdentities.end(), KeyPair(k)))
|
|
m_myIdentities.append(KeyPair(k));
|
|
}
|
|
}
|
|
main()->web3Server()->setIdentities(keysAsVector(m_myIdentities));
|
|
refreshWhisper();
|
|
}
|
|
|
|
void Whisper::writeSettings(QSettings& _s)
|
|
{
|
|
QByteArray b;
|
|
b.resize(sizeof(Secret) * m_myIdentities.size());
|
|
auto p = b.data();
|
|
for (auto i: m_myIdentities)
|
|
{
|
|
memcpy(p, &(i.secret()), sizeof(Secret));
|
|
p += sizeof(Secret);
|
|
}
|
|
_s.setValue("identities", b);
|
|
}
|
|
|
|
void Whisper::addNewId(QString _ids)
|
|
{
|
|
KeyPair kp(jsToSecret(_ids.toStdString()));
|
|
m_myIdentities.push_back(kp);
|
|
main()->web3Server()->setIdentities(keysAsVector(m_myIdentities));
|
|
refreshWhisper();
|
|
}
|
|
|
|
void Whisper::refreshWhisper()
|
|
{
|
|
m_ui->shhFrom->clear();
|
|
for (auto i: main()->web3Server()->ids())
|
|
m_ui->shhFrom->addItem(QString::fromStdString(toHex(i.first.ref())));
|
|
}
|
|
|
|
void Whisper::on_newIdentity_triggered()
|
|
{
|
|
KeyPair kp = KeyPair::create();
|
|
m_myIdentities.append(kp);
|
|
main()->web3Server()->setIdentities(keysAsVector(m_myIdentities));
|
|
refreshWhisper();
|
|
}
|
|
|
|
void Whisper::on_post_clicked()
|
|
{
|
|
return;
|
|
shh::Message m;
|
|
m.setTo(stringToPublic(m_ui->shhTo->currentText()));
|
|
m.setPayload(parseData(m_ui->shhData->toPlainText().toStdString()));
|
|
Public f = stringToPublic(m_ui->shhFrom->currentText());
|
|
Secret from;
|
|
if (main()->web3Server()->ids().count(f))
|
|
from = main()->web3Server()->ids().at(f);
|
|
whisper()->inject(m.seal(from, topicFromText(m_ui->shhTopic->toPlainText()), m_ui->shhTtl->value(), m_ui->shhWork->value()));
|
|
}
|
|
|